


/*----------------------------------------------------------------------------------------
当前实现的命令

#if 0
3.2  读取白名单  readWhiteList
3.4  读取分组名称数量 readGroupNameNum 
3.5  读取分组 readGroup	16
3.7  配置场景  setScence	18
3.8  读取场景  readScence	20
3.9  配置绑定  setBind	21
3.10  读取绑定  readBind	22

3.14  读网关信息  readGwMsg	34
3.15  设置网关  setupGw	35
3.16  读网关配置 readGwSetup	36
3.17  读白名单在网设备 readOnlineInList	37
3.18  读非白名单在网设备 readOnlineNoList	38


3.20  重启网关  resetGw	40
////3.21  删除白名单  delWhiteList	40
3.22  外部信号输入 extenalSignal	41
////3.23  删除场景 delScence	41
////3.24  执行场景 execScence	42
3.25  读取所有绑定列表 readBindAllHead	42
////3.26  绑定删除   bindDel	43
3.27 读取设备pid：   readPid	43
3.28  同步场景数据   syncScene	44

3.32   读取主平台ip端口  mainIpRead	47
3.33  设置主平台ip端口   mainIpSet	47
3.35  读取网关io状态      gwIoRead	48
3.36  设置网关io（继电器） 状态  gwIoSet	49
3.36.1   全部output同时设	49
3.36.2    指定设置某个或某几个output	49
3.37  读取定时任务    timingTaskRead	50
3.38  设置定时任务   timingTaskSet	51
3.39  读取网关以太网ip信息  gwEthIpRead	52
3.40  设置网关以太网ip信息  gwEthIpSet	52
3.41  读取网关网络状态信息  gwIfconfigRead	53

#endif





#if 0
3，下行指令详述
json项为 cmd， value为各个命令字符串。需要应答， 应答json项为response。
“head”项是固定的，不同指令间是”指令类型”的区别：
cmd/response/notify/indicate/confirm 五选一。
下面的head项陈述，可能只写”指令类型”，而忽略其他的固定项。
“body”,”data”,”attrLst”是有效数据。

3.1  配置白名单  setWhiteList
3.1.1 下行命令:
{
“head”:{
  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
  “msgId”:12345,           // 消息序列号
  “timeStamp”:12345678,    // unix 时间
  “cmd”:”setWhiteList”      // 指令类型为：cmd
},
“body”:[
{ "name":"lamp1",            //  灯的名称， 用户输入的， 不同设备不可同名。
           "mac":"112233445566",  // 灯mac地址， 固定的，用户扫描或手动输入
           “nodeType”:0,
           “channel”:1,
           “privAddr”:23,
           "pid": "xxxxxx",       // 产品类别， 平台预先定好的
           “model”:”NBE_32LE5B”, // 产品型号， 可选
          “propertyId”:2,                    // 资产id（灯杆号）， 可选
          “propertyName”:”abcdfegggg”       //  资产名称， 可选
          “mainGroupNo”:3,                // 路灯分组号， 可选
          “label”:”xxx”                  // 标签（别名），可选，不同设备可以同名，默认同name
}
]
}

#endif 


#if 0

兼容mqtt， tcp， udp， 串口通讯。
tcp， udp 指定ip， 端口号；串口指定串口号， 波特率；mqtt指定ip， 端口号，1个指令使用一个topic。数据包的功能由“cmd”字段决定。暂未使用加密传输。网关采用udp广播自动发现主机。字符串只支持ASC码和GB2313，不支持UTF8。

提示：本文档为内部开发文档，只为阐述清楚实现逻辑，未对文字进行校对，可能有字符的错误或遗落。 特别是json格式数据，请以正常json格式为准。

1.1 数据包简要解析
数据包由head和body以及其他一些项组成，head指示包的来源目的，功能，时间戳等信息。body是有效数据。例子如下：
{
“head”:{
   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码
  “gatewayId”:”xxxxxx”,      // 消息相关的网关编号
  “msgId”:12345,           // 消息序列号
  “timeStamp”:12345678,    // unix 时间
  “cmd”:”setWhiteList”      // 指令类型
},
“body”:[                 // body 表示数组
{
    "name":"lamp1",            //  灯的名称， 用户输入的
    "mac":"112233445566",  // 灯mac地址， 固定的，用户扫描或手动输入
    "pid": "xxxxxx",                // 产品类别， 平台预先定好的
}
],
“data”:{                       // data 表示单项json
   “item1”:”1234”
}
}
实际发出的数据包最后加一字节’\n’作为结束符。

head项解析：
replaceId ：
当消息是网关发出时， 表示数据目的id。
当消息是发给网关的， 则表示数据来源id。
作为来源时， 是唯一标识字符串。
作为目的时，可以表示广播，组播，和定点发送。
广播是发给所有连接设备。字符串长度为0时表示广播。
 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。

#endif

-------------------------------------------------------------------------------------------------------------------------------- */



//  gcc ./cJSON/cJSON.c cjson_test.c -o 1  -lm
//  gcc cJSON.c cjson_test.c -o cjson_test  -lm



#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

//#include "Node95.h"
//#include "bsp_dev.h"
//#include "global.h"


#include "cjson_api_readAttr.h"
#include "dev_4g.h"
#include "iot_node.h"
#include "meter.h"
#include "print_log.h"  


#include "cJSON.h"
#include "gui_logist.h"

#include "string_tools.h"
#include "gw_ktj_tcp_client.h"
#include "device_data_struct.h"


#include "tcp_api_01.h" 
#include "iotv30_tcp_client.h" 

#include "cjson_api_back.h"
#include "gui_cjson_api.h"


//unsigned int  gui_msg_id =1234;


unsigned int  gui_js_api_msg_id = 0;
volatile unsigned int  gui_js_api_timeStamp = 0;


//3.5  读取分组 readGroup
void json_read_cmd_readGroup(const char* cmd_str,const char* cct_id_str,const int msg_id );

//3.22  外部信号输入 extenalSignal
void json_read_cmd_extenalSignal(const char* cmd_str,const char* cct_id_str,const int msg_id );

//3.27 读取设备pid：   readPid    
void json_read_cmd_readPid(const char* cmd_str,const char* cct_id_str,const int msg_id );

//3.28  同步场景数据   syncScene
void json_read_cmd_syncScene(const char* cmd_str,const char* cct_id_str,const int msg_id );


void json_readback_readWhiteList(const char *pstr, const void *param); ////3.2  读取白名单  readWhiteList
void json_readback_readOnlineInList(const char *pstr, const void *param); ////3.17  读白名单在网设备 readOnlineInList	37
void json_readback_readOnlineNoList(const char *pstr, const void *param); ////3.18  读非白名单在网设备 readOnlineNoList	38---鸡肋-----实际上PLC开放性组网没办法区分是否是在白名单之内

void json_readback_gwIoRead(const char *pstr, const void *param); //3.35  读取网关io状态      gwIoRead	48

 //----readAttr-----
void json_readback_readAttr(const char *pstr, const void *param);




#if 1
///#define    READ_CMD_TAB_MAX  (16U)

 const read_cmd_st read_cmd_tab[READ_CMD_TAB_MAX]={
//	{"readWhiteList",    json_read_cmd},      //3.2  读取白名单  readWhiteList-------------------根据逻辑需要---读白名单需要放在第一位
	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34----读取网关4G模块信息
	{"mainIpRead",      json_read_cmd},      ////3.32   读取主平台ip端口  mainIpRead	47
	{"gwIfconfigRead",  json_read_cmd},      ////3.41  读取网关网络状态信息  gwIfconfigRead	53

};

#endif


#if 0    /////gui_app时 用这个
 const read_cmd_st read_cmd_tab[READ_CMD_TAB_MAX]={
	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34----读取网关4G模块信息

    {"readWhiteList",    json_read_cmd},      //3.2  读取白名单  readWhiteList-------------------根据逻辑需要---读白名单需要放在第一位/
	{"readOnlineInList", json_read_cmd},      ////3.17  读白名单在网设备 readOnlineInList	37
	{"mainIpRead",      json_read_cmd},      ////3.32   读取主平台ip端口  mainIpRead	47
	{"gwIoRead",        json_read_cmd},      ////3.35  读取网关io状态      gwIoRead	48
	{"gwEthIpRead",     json_read_cmd},      ////3.39  读取网关以太网ip信息  gwEthIpRead	52
	{"gwIfconfigRead",  json_read_cmd},      ////3.41  读取网关网络状态信息  gwIfconfigRead	53

};
#endif


  
////--------周期读取数据----当前还没有用到----------------------
#define    PERIOD_READ_CMD_TAB_MAX  (5U)

 const read_cmd_st period_read_cmd_tab[PERIOD_READ_CMD_TAB_MAX]={
	{"readWhiteList",    json_read_cmd},      //3.2  读取白名单  readWhiteList-------------------根据逻辑需要---读白名单需要放在第一位
	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34----读取网关4G模块信息
	{"readOnlineInList", json_read_cmd},      ////3.17  读白名单在网设备 readOnlineInList	37

	{"gwEthIpRead",     json_read_cmd},      ////3.39  读取网关以太网ip信息  gwEthIpRead	52
	{"gwIfconfigRead",  json_read_cmd},      ////3.41  读取网关网络状态信息  gwIfconfigRead	53

//	{"extenalSignal",    json_read_cmd_extenalSignal},      ////3.22  外部信号输入 extenalSignal	41

};






#if 0
 const read_cmd_st read_cmd_tab[READ_CMD_TAB_MAX]={
	{"readWhiteList",    json_read_cmd},      //3.2  读取白名单  readWhiteList-------------------根据逻辑需要---读白名单需要放在第一位
	{"readGroupNameNum", json_read_cmd},      //3.4  读取分组名称数量 readGroupNameNum 
	{"readGroup",json_read_cmd_readGroup},    //3.5  读取分组 readGroup	16
	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34----读取网关4G模块信息
	{"readGwSetup",      json_read_cmd},      ////3.16  读网关配置 readGwSetup	36
	{"readOnlineInList", json_read_cmd},      ////3.17  读白名单在网设备 readOnlineInList	37
	{"readOnlineNoList", json_read_cmd},      ////3.18  读非白名单在网设备 readOnlineNoList	38
	{"extenalSignal",    json_read_cmd_extenalSignal},      ////3.22  外部信号输入 extenalSignal	41
	{"readBindAllHead", json_read_cmd},      ////3.25  读取所有绑定列表 readBindAllHead	42
	{"readPid",         json_read_cmd_readPid},      ///3.27 读取设备pid：   readPid    
	{"syncScene",        json_read_cmd_syncScene},      ////3.28  同步场景数据   syncScene	44
	{"mainIpRead",      json_read_cmd},      ////3.32   读取主平台ip端口  mainIpRead	47
	{"gwIoRead",        json_read_cmd},      ////3.35  读取网关io状态      gwIoRead	48
	{"timingTaskRead",  json_read_cmd},      ////3.37  读取定时任务    timingTaskRead	50
	{"gwEthIpRead",     json_read_cmd},      ////3.39  读取网关以太网ip信息  gwEthIpRead	52
	{"gwIfconfigRead",  json_read_cmd},      ////3.41  读取网关网络状态信息  gwIfconfigRead	53

};
#endif



  void (*func)(const char *cmd_str, const char* cct_id_str,const int msg_id );
  
////--------周期读取所有命令的数据----当前还没有用到----------------------
#define    PERIOD_READ_ALL_CMD_TAB_MAX  (16U)

 const read_cmd_st period_read_all_cmd_tab[PERIOD_READ_ALL_CMD_TAB_MAX]={
	{"readWhiteList",    json_read_cmd},      //3.2  读取白名单  readWhiteList-------------------根据逻辑需要---读白名单需要放在第一位
	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34----读取网关4G模块信息	
    {"readGroupNameNum", json_read_cmd},      //3.4  读取分组名称数量 readGroupNameNum 
	{"readGroup",json_read_cmd_readGroup},    //3.5  读取分组 readGroup	16

	{"readGwSetup",      json_read_cmd},      ////3.16  读网关配置 readGwSetup	36
	{"readOnlineInList", json_read_cmd},      ////3.17  读白名单在网设备 readOnlineInList	37
	{"readOnlineNoList", json_read_cmd},      ////3.18  读非白名单在网设备 readOnlineNoList	38--------鸡肋-----实际上PLC开放性组网没办法区分是否是在白名单之内
	{"extenalSignal",    json_read_cmd_extenalSignal},      ////3.22  外部信号输入 extenalSignal	41
	{"readBindAllHead", json_read_cmd},      ////3.25  读取所有绑定列表 readBindAllHead	42
	{"readPid",         json_read_cmd_readPid},      ///3.27 读取设备pid：   readPid    
	{"syncScene",        json_read_cmd_syncScene},      ////3.28  同步场景数据   syncScene	44
	{"mainIpRead",      json_read_cmd},      ////3.32   读取主平台ip端口  mainIpRead	47
	{"gwIoRead",        json_read_cmd},      ////3.35  读取网关io状态      gwIoRead	48
	{"timingTaskRead",  json_read_cmd},      ////3.37  读取定时任务    timingTaskRead	50
	{"gwEthIpRead",     json_read_cmd},      ////3.39  读取网关以太网ip信息  gwEthIpRead	52
	{"gwIfconfigRead",  json_read_cmd},      ////3.41  读取网关网络状态信息  gwIfconfigRead	53

};





#define    READ_BACK_TAB_MAX  (10U)

 const read_back_st read_back_tab[READ_BACK_TAB_MAX]={

    {"readAttr",    json_readback_readAttr_single},         //3.12  读属性  readAttr  接收应答解析-------当前实现--读液位传感器的解析
    {"setAttr",    json_writeback_setAttr},   ////  写属性  setAttr  接收应答解析
 
    //	{"readAttr",       json_readback_readAttr},            ////3.12  读属性  readAttr ---------------------------------------------------当前实现---读电表的解析
 	{"readGwMsg",      json_readback_readGwMsg},           ////3.14  读网关信息  readGwMsg  ---包括网关4G模块信息   
	{"mainIpRead",     json_readback_mainIpRead},          ////3.32   读取主平台ip端口  mainIpRead
	{"gwEthIpRead",    json_readback_gwEthIpRead},         ////3.39  读取网关以太网ip信息  gwEthIpRead
	{"gwIfconfigRead", json_readback_gwIfconfigRead},      ////3.41  读取网关网络状态信息  gwIfconfigRead  
 	{"gwIoRead",       json_readback_gwIoRead},            ////3.35  读取网关io状态      gwIoRead	48
	{"readWhiteList",  json_readback_readWhiteList},        ////3.2  读取白名单  readWhiteList
 	{"readOnlineInList", json_readback_readOnlineInList},      ////3.17  读白名单在网设备 readOnlineInList	37
	{"readOnlineNoList", json_readback_readOnlineNoList},      ////3.18  读非白名单在网设备 readOnlineNoList	38

 };




/*
3.14  读网关信息  readGwMsg  
下行
{
   “head”:{
       ..........
       “cmd”:”readGwMsg”
},
}
上行
{
“head”:{
       ..........
       “response”:”readGwMsg”
},
“data”:{
   “hwVer”:”xxx”,
   “swVer”:”xxx”,
   “plcMac”:”xxx”,
   “bleMac”:”xxxx”,
   “usrMsg”:”xxxxx”,-----------------这个没有数据对应????/
“gatewayId”:”xxxxxxx”
}
}

{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34
	{"readGwSetup",      json_read_cmd},      ////3.16  读网关配置 readGwSetup	36

*/



//3.14  读网关信息  readGwMsg  

void json_readGwMsg( void )
{
	 json_read_cmd("readGwMsg", "", gui_js_api_msg_id++ );    ////3.14  读网关信息  readGwMsg	34
}


//  ret = 0,获取到CSQ  ;ret = 1,没有获取到CSQ;ret = 2,CSQ=0 ;
uint8_t  decode_CSQ( char* rx_buf ,char* get_csq,char* get_ccid )
{/////just for testing

int16_t tmp1,tmp2;
char  str[4];


if( (NULL==rx_buf) ||  (NULL==get_csq) ||  (NULL==get_ccid) )
{		
    return 1;
}


//reg=1,csq=31,卡号898604C51022D1106257, 

	tmp1 = FindStringRetIndex( rx_buf,"csq=");
	
	if( tmp1< 0)	
	{		
      *get_csq = 0 ; 	
	   return 2;	
	}


	tmp1=tmp1+strlen("csq="); 
	
	tmp2 = FindStringRetIndex( &rx_buf[tmp1],",") ;	
	if( tmp2< 0)
    {
        *get_csq = 0 ; 	       
        return 2;	
    }	

	
	tmp2 -=tmp1;
	
	memset(str,0,4);
//	memcpy( str,&rx_buf[tmp1],tmp2 );//  9  12 max--31
    strncpy( str,&rx_buf[tmp1],tmp2 );//  9  12 max--31   
	
	*get_csq = atoi16( str, 10 );
	

//reg=1,csq=31,卡号898604C51022D1106257, 


  return 0 ;		
	
}



//3.14  读网关信息  readGwMsg  接收应答解析
void json_readback_readGwMsg(const char *pstr, const void *param)
{
	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	unsigned int msg_id = 0;

	unsigned int sim_flag,tmp;

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
		return ;
	}


//{"head":{"gatewayId":"gw_0000C0A8011B","replaceId":"","msgId":0,"timeStamp":1711939775,"response":"readGwMsg"},
//"data":{"swVer":"2.4.22","hwVer":"1.0.0","plcMac":"0000C0A8011B","ethMac":"112233445568","wifiMac":"112233445569",
//"masterId":"masterId","pid":"010100","gatewayId":"gw_0000C0A8011B",
//"usrMsg":"soTrans-V1.0.3,soGwc-V1.0.2,soPlc-V1.0.1,so485-V1.0.1,creg=1,csq=31,卡号898604C51022D1106268, 
//route=eth0, ip=192.168.1.250:10086, 管理平台:0, 有网线","Ip":"192.168.1.216","bleMac":"network_monitor-v1.1.3"}}




//无卡时返回："simcard":0,"csq":0,"CCID":""

// {"head":{"gatewayId":"gw_1C32830600E4","replaceId":"gw_1743414967133","msgId":0,"timeStamp":1743414968,"response":"readGwMsg"},
// "data":{"swVer":"2.6.4a","hwVer":"1.0.0","plcMac":"1C32830600E4","ethMac":"112233445568","wifiMac":"112233445569",
// "eth0":"192.168.1.200","pid":"010100","gatewayId":"gw_1C32830600E4",
// "usrMsg":"soTrans-V1.0.3,soGwc-V1.0.2,soPlc-V1.0.1,so485-V1.0.1,creg=1,csq=31, CCID=898604C51022D1106257, route=eth0, ip=139.9.25.211:10086, 管理平台:1, 有网线, 无加密",
// "Ip":"192.168.1.66","bleMac":"network_monitor-v1.2.5",
// "simcard":1,"csq":31,"CCID":"898604C51022D1106257"}}




	msg_id = get_input_msgId(json);

	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {
        
		json_item = cJSON_GetObjectItem(json_data, "hwVer" );
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.hwVer,0,sizeof(gui_gw_param.nv_gw_msg.hwVer) );
              strncpy(gui_gw_param.nv_gw_msg.hwVer,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.hwVer) );
		}

		json_item = cJSON_GetObjectItem(json_data, "swVer" ); 
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.swVer,0,sizeof(gui_gw_param.nv_gw_msg.swVer) );
              strncpy(gui_gw_param.nv_gw_msg.swVer,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.swVer) );
		}


		json_item = cJSON_GetObjectItem(json_data, "plcMac" );
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.plcMac,0,sizeof(gui_gw_param.nv_gw_msg.plcMac) );
              strncpy(gui_gw_param.nv_gw_msg.plcMac,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.plcMac) );
		}

          //"bleMac":"network_monitor-v1.1.3"
		json_item = cJSON_GetObjectItem(json_data, "bleMac" );
		if(json_item) {
//              memset(gui_gw_param.nv_gw_msg.bleMac,0,sizeof(gui_gw_param.nv_gw_msg.bleMac) );
             // strncpy(gui_gw_param.nv_gw_msg.bleMac,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.bleMac) );//数据溢出
              memset(gui_gw_com.bleMac,0,sizeof(gui_gw_com.bleMac) );
              strncpy(gui_gw_com.bleMac,json_item->valuestring,sizeof(gui_gw_com.bleMac) );//             
		}

		json_item = cJSON_GetObjectItem(json_data, "wifiMac" );
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.wifiMac,0,sizeof(gui_gw_param.nv_gw_msg.wifiMac) );
              strncpy(gui_gw_param.nv_gw_msg.wifiMac,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.wifiMac) );
		}

		json_item = cJSON_GetObjectItem(json_data, "ethMac" );
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.ethMac,0,sizeof(gui_gw_param.nv_gw_msg.ethMac) );
              strncpy(gui_gw_param.nv_gw_msg.ethMac,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.ethMac) );
		}


		json_item = cJSON_GetObjectItem(json_data, "gatewayId" );
		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.gatewayId,0,sizeof(gui_gw_param.nv_gw_msg.gatewayId) );
              strncpy(gui_gw_param.nv_gw_msg.gatewayId,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.gatewayId) );
		}


//无卡时返回："simcard":0,"csq":0,"CCID":""
// "simcard":1,"csq":31,"CCID":"898604C51022D1106257"}}

        json_item = cJSON_GetObjectItem(json_data, "simcard" );
        if(json_item) {
            sim_flag =  cJSON_GetNumberValue(json_item);  
        }else{
            sim_flag = 0;
        }

       logout("simcard=%d\n",sim_flag);

        json_item = cJSON_GetObjectItem(json_data, "csq" );
        if(json_item) {
            // hcat1.CSQ = json_item->valueint
            gui_gw_param.csq =  hcat1.CSQ =   cJSON_GetNumberValue(json_item);  
            logout("hcat1.CSQ=%d\n",hcat1.CSQ);
        }

        json_item = cJSON_GetObjectItem(json_data, "CCID" );
        if(json_item) {
            memset(hcat1.CCID,0,sizeof(hcat1.CCID) );
            // strncpy(hcat1.CCID,json_item->valuestring,sizeof(hcat1.CCID) );
            strncpy(hcat1.CCID,cJSON_GetStringValue(json_item),sizeof(hcat1.CCID) );    
            logout("hcat1.CCID=%s\n",hcat1.CCID);       
        }
        

        if(0==sim_flag )
        { ////"simcard":0,-----没插卡

            gui_gw_param.csq =  hcat1.CSQ = 0;
            memset(hcat1.CCID,0,sizeof(hcat1.CCID) );
        }



#if  1     //这部分数据暂时不清楚

//"usrMsg":"soTrans-V1.0.3,soGwc-V1.0.2,soPlc-V1.0.1,so485-V1.0.1,无sim卡, 
//route=eth0, ip=139.9.25.211:10086, 管理平台:0, 有网线","Ip":"192.168.0.101","bleMac":"network_monitor-v1.1.3"}} 


// "data": {
//     "swVer": "2.6.4",
//     "hwVer": "1.0.0",
//     "plcMac": "1C32830600E4",
//     "ethMac": "112233445568",
//     "wifiMac": "112233445569",
//     "eth0": "192.168.1.200",
//     "pid": "010100",
//     "gatewayId": "gw_1C32830600E4",
//     "usrMsg": "soTrans-V1.0.3,soGwc-V1.0.2,soPlc-V1.0.1,so485-V1.0.1,creg=1,csq=31,卡号898604C51022D1106257, route=eth0, ip=139.9.25.211:10086, 管理平台:1, 有网线, 无加密",
//     "Ip": "192.168.1.95",
//     "bleMac": "network_monitor-v1.2.5"
// }

		json_item = cJSON_GetObjectItem(json_data, "usrMsg" );

		if(json_item) {
              memset(gui_gw_param.nv_gw_msg.usrMsg,0,sizeof(gui_gw_param.nv_gw_msg.usrMsg) );
              strncpy(gui_gw_param.nv_gw_msg.usrMsg,json_item->valuestring,sizeof(gui_gw_param.nv_gw_msg.usrMsg) );

            // ret = 0,没有获取到CSQ ;ret = 1,获取到CSQ ;ret = 2,CSQ=0 ;
            //  if( !decode_CSQ( gui_gw_param.nv_gw_msg.usrMsg ) ) 
            //  {
            //     //	obj->Flag.bit.sim_ok   = 1;
            //     log_debug("sim not ok");
            //  }else{
            //    //UBIA4G_Obj.Flag.bit.has_sim  = 1;
            //    //UBIA4G_Obj.Flag.bit.sim_ok   = 1;
              
            //  }


             if( FindStringFast(gui_gw_param.nv_gw_msg.usrMsg,"无sim卡") )  
             {
                 log_debug("无sim卡\n");
                // UBIA4G_Obj.Flag.bit.has_sim  = 0;
                // UBIA4G_Obj.Flag.bit.sim_ok   = 0;

             }

            // FindStringFast(char* s,const char* t);
            // FindStringRetIndex(char* s,const char* t);

		}

#endif


		//commit_gw_status();
	}


	if (json) {
		cJSON_Delete(json);
	}	

	
	//int ret = 0 ; // .......  bind_set_json

	// response
	//response_server_comm("setGwTime",msg_id, ret, param);

}


/*--------------------------------------------------------------------------
#if 0
gui_logist_tick_sec index=0 ,tx_cmd=readWhiteList
json_read_cmd,cmd=readWhiteList,id=gw_0000C0A8011B
{
        "head": {
                "gatewayId":    "gw_0000C0A8011B",
                "msgId":        1250,
                "timeStamp":    1548640861,
                "cmd":  "readWhiteList"
        }
}
Tcp_Client_Recv data form server:

{"head":{"gatewayId":"gw_0000C0A8011B","replaceId":"","msgId":1250,"timeStamp":1548640868,"response":"readWhiteList"},"totalFrame":2,"currFrame":1,"totalWhitelist":17,
"body":[
{"mac":"1C3283040046","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0046","pid":"1001"},
{"mac":"1C3283040044","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0044","pid":"1001"},
{"mac":"1C3283040027","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0027","pid":"1001"},
{"mac":"777777770009","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0009","pid":"1001"},
{"mac":"1C328304002F","nodeType":0,"channel":0,"privAddr":0,"name":"bk_002f","pid":"1001"},
{"mac":"1C3283000C4B","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0c4b","pid":"1111"},
{"mac":"0000C0A80165","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0165","pid":"0202"},
{"mac":"1C3283001C72","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_1c72","pid":"1111"},
{"mac":"C8F742FEBB01","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_bb01","pid":"0202"},
{"mac":"1C3283001DC1","nodeType":0,"channel":0,"privAddr":0,"name":"rLampCW_1dc1","pid":"1212"},
{"mac":"1C3283000C19","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0c19","pid":"1111"},
{"mac":"1C3283000B14","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0b14","pid":"1111"},
{"mac":"1C3283040045","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0045","pid":"1001"},
{"mac":"1C3283040026","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0026","pid":"1001"},
{"mac":"1C3283000917","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0917","pid":"0202"}]}

Tcp_Client_Recv data form server:

{"head":{"gatewayId":"gw_0000C0A8011B","replaceId":"","msgId":1250,"timeStamp":1548640868,"response":"readWhiteList"},
"totalFrame":2,"currFrame":2,"totalWhitelist":17,
"body":[
{"mac":"1C3283000907","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0907","pid":"0202"},
{"mac":"1C3283000904","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0904","pid":"0202"}]}
1C3283040027","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0027","pid":"1001"},-------------------------------------------这里数据丢失------
{"mac":"777777770009","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0009","pid":"1001"},
{"mac":"1C328304002F","nodeType":0,"channel":0,"privAddr":0,"name":"bk_002f","pid":"1001"},
{"mac":"1C3283000C4B","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0c4b","pid":"1111"},
{"mac":"0000C0A80165","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0165","pid":"0202"},
{"mac":"1C3283001C72","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_1c72","pid":"1111"},
{"mac":"C8F742FEBB01","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_bb01","pid":"0202"},
{"mac":"1C3283001DC1","nodeType":0,"channel":0,"privAddr":0,"name":"rLampCW_1dc1","pid":"1212"},
{"mac":"1C3283000C19","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0c19","pid":"1111"},
{"mac":"1C3283000B14","nodeType":0,"channel":0,"privAddr":0,"name":"roadLamp_0b14","pid":"1111"},
{"mac":"1C3283040045","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0045","pid":"1001"},
{"mac":"1C3283040026","nodeType":0,"channel":0,"privAddr":0,"name":"bk_0026","pid":"1001"},
{"mac":"1C3283000917","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0917","pid":"0202"}]}


#endif

------------------------------------------------------------------- */




// void json_readback_readOnlineInList(const char *pstr, const void *param); ////3.17  读白名单在网设备 readOnlineInList	37
// void json_readback_readOnlineNoList(const char *pstr, const void *param); ////3.18  读非白名单在网设备 readOnlineNoList	38


void json_readback_readWhiteList(const char *pstr, const void *param)
{

#if  0  ////------json_readback_readWhiteList--------------///

	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	cJSON *json_data_array = NULL;
	cJSON *json_item_array = NULL;

    int    json_data_array_size = 0, i = 0;
	unsigned int msg_id = 0;

    uint8_t  uctmp;

    int currFrame ;

     NodeCore_st  node_core;


    log_debug("%s() start\n",__FUNCTION__);


	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
        log_debug("not json string\n");
		return ;
	}

	msg_id = get_input_msgId(json);


     //文档是有data结构，实际测试没有
    // “data”: {               // 可选，用于指示分帧
    // “totalFrame”:2,          //如果白名单太长，可能要分帧， 没有此项，则为1帧。
    // “currFrame”:1,           // 第一帧
    // },

	json_data = cJSON_GetObjectItem(json, "data"); //与文档描述不符----“data”: {    // 可选，用于指示分帧

	if(json_data) {
        
   		json_item = cJSON_GetObjectItem(json_data, "totalWhitelist" );
		if(json_item) {
           // Node_SetNum( cJSON_GetNumberValue(json_item ) );
		}
     
    }else{ //没有data 字段

           //"totalFrame":2,"currFrame":2,"totalWhitelist":17,
   		json_item = cJSON_GetObjectItem(json, "totalWhitelist" );
		if( json_item) {
           // Node_SetNum( cJSON_GetNumberValue(json_item ) );
            log_debug("totalWhitelist=%f\n",cJSON_GetNumberValue(json_item ));
		}

   		json_item = cJSON_GetObjectItem(json, "currFrame" );
		if( json_item) {
             currFrame = cJSON_GetNumberValue(json_item ) ;
             if(1== currFrame)
             {
                 Node_Clear( );  //ver "4.7" 
             }
              
            log_debug("currFrame=%d\n",currFrame );

		}

    }





//	cJSON *body = cJSON_CreateArray();
// "body":[
// {"mac":"1C3283000907","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0907","pid":"0202"},
// {"mac":"1C3283000904","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0904","pid":"0202"}]}

	json_data_array = cJSON_GetObjectItem(json, "body");

	if( json_data_array ) {      

       json_data_array_size = cJSON_GetArraySize(json_data_array);
       log_debug("json_data_array_size=%d\n",json_data_array_size);


            for(i = 0; i < json_data_array_size; i++)
            {
                json_item_array = cJSON_GetArrayItem(json_data_array, i);

                if( json_item_array ) 
                {

                   json_item = cJSON_GetObjectItem(json_item_array, "mac" );

                    if(json_item) {
                         memset(node_core.Config.ID_str,0,sizeof(node_core.Config.ID_str) );
                         strncpy(node_core.Config.ID_str,json_item->valuestring,sizeof(node_core.Config.ID_str) );
       
                         log_debug("mac=%s\n",node_core.Config.ID_str );
                    }


                   //node_core.Config.Type = cJSON_GetNumberValue(cJSON_GetObjectItem(json_item_array, "nodeType" ) ); 
                   json_item = cJSON_GetObjectItem(json_item_array, "nodeType" );

                    if(json_item) {
                         node_core.Config.nodeType = cJSON_GetNumberValue(json_item);      
                         log_debug("Type=%d\n", node_core.Config.nodeType );
                    }

                   //node_core.Config.channel  = cJSON_GetNumberValue(cJSON_GetObjectItem(json_item_array, "channel" ) );
                   json_item = cJSON_GetObjectItem(json_item_array, "channel" );

                    if(json_item) {
                         node_core.Config.channel  = cJSON_GetNumberValue(json_item);  
                         log_debug("channel=%d\n", node_core.Config.channel );

                    }

 
                   json_item = cJSON_GetObjectItem(json_item_array, "privAddr" );

                    if(json_item) {
                         node_core.Config.privAddr = cJSON_GetNumberValue(json_item);          
                         log_debug("privAddr=%d\n", node_core.Config.privAddr );
                    }



                   json_item = cJSON_GetObjectItem(json_item_array, "pid" );

                    if(json_item) {
                         strncpy(node_core.Config.pid ,cJSON_GetStringValue(json_item) , sizeof(node_core.Config.pid) );          
                         log_debug("pid=%s\n", node_core.Config.pid );
                    }

                   json_item = cJSON_GetObjectItem(json_item_array, "deviceName" );

                    if(json_item) {
                         strncpy(node_core.Config.deviceName ,cJSON_GetStringValue(json_item) , sizeof(node_core.Config.deviceName) );          
                         log_debug("deviceName=%s\n", node_core.Config.deviceName );
                    }


                   //node_core.Config.Group = cJSON_GetNumberValue(cJSON_GetObjectItem(json_item_array, "mainGroupNo" ) );    
                   json_item = cJSON_GetObjectItem(json_item_array, "mainGroupNo" );

                    if(json_item) {
                         node_core.Config.Group = cJSON_GetNumberValue(json_item);          
                         log_debug("Group=%d\n", node_core.Config.Group );
                    }



                  //uctmp = cJSON_GetNumberValue(cJSON_GetObjectItem(json_item_array, "online" ) );    //“online”:1    // 1 在线， 0离线
                   json_item = cJSON_GetObjectItem(json_item_array, "online" );

                    if(json_item) {
                         uctmp = cJSON_GetNumberValue(json_item);  

                         if( uctmp )
                         {
                            node_core.Flag.bit.online = 1;
                         }else{
                            node_core.Flag.bit.online = 0;
                         }
                         
                         log_debug("online=%d\n", uctmp );
                    }


                        //Node_New( cJSON_GetStringValue(json_item ), group, type,i );
                        // Node_Add( Node_New( cJSON_GetStringValue(json_item ), group, type,i ) );
                        Node_Add( &node_core );                        

                }  // ---- if( json_item_array ) 
  
            }  //---for

	}

    log_debug("%s() end\n",__FUNCTION__);

	if (json) {
		cJSON_Delete(json);
	}



#endif      ////------json_readback_readWhiteList--------------///

}






// 上行
// {
//  “head”:{
//    .............
//   “response”:”readOnlineInList”     //
// },
// “totalFrame”:2,
// “currFrame”:1,
// “body”:[
// { "name":"lamp1",            //  灯的名称， 用户输入的
//     "mac":"112233445566",  // 灯mac地址， 固定的，用户扫描或手动输入
//     "pid": "xxxxxx",                // 产品类别， 平台预先定好的
// },
// { "name":"lamp2",            //  灯的名称， 用户输入的
//     "mac":"112233445567",  // 灯mac地址， 固定的，用户扫描或手动输入
//     "pid": "xxxxxx",                // 产品类别， 平台预先定好的
// },
// ]




////3.17  读白名单在网设备 readOnlineInList	37
void json_readback_readOnlineInList(const char *pstr, const void *param)
{

#if 0


	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	cJSON *json_data_array = NULL;
	cJSON *json_item_array = NULL;

    int    json_data_array_size = 0, i = 0;
	unsigned int msg_id = 0;

    uint8_t  uctmp;

    int currFrame ;

    log_debug("%s() start\n",__FUNCTION__);

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
        log_debug("not json string\n");
		return ;
	}

	msg_id = get_input_msgId(json);

           //"totalFrame":2,"currFrame":2,
   		json_item = cJSON_GetObjectItem(json, "totalFrame" );
		if( json_item) {
            log_debug("totalFrame=%f\n",cJSON_GetNumberValue(json_item ));
		}

   		json_item = cJSON_GetObjectItem(json, "currFrame" );
		if( json_item) {
             currFrame = cJSON_GetNumberValue(json_item ) ;
            log_debug("currFrame=%d\n",currFrame );
		}


// “totalFrame”:2,
// “currFrame”:1,
// “body”:[
// { "name":"lamp1",            //  灯的名称， 用户输入的
//     "mac":"112233445566",  // 灯mac地址， 固定的，用户扫描或手动输入
//     "pid": "xxxxxx",                // 产品类别， 平台预先定好的
// },


//	cJSON *body = cJSON_CreateArray();
// "body":[
// {"mac":"1C3283000907","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0907","pid":"0202"},
// {"mac":"1C3283000904","nodeType":0,"channel":0,"privAddr":0,"name":"lamp2_0904","pid":"0202"}]}

	json_data_array = cJSON_GetObjectItem(json, "body");

	if( json_data_array ) {      

       json_data_array_size = cJSON_GetArraySize(json_data_array);
       log_debug("json_data_array_size=%d\n",json_data_array_size);


            for(i = 0; i < json_data_array_size; i++)
            {
                json_item_array = cJSON_GetArrayItem(json_data_array, i);

                if( json_item_array ) 
                {

                   json_item = cJSON_GetObjectItem(json_item_array, "mac" );

                    if(json_item) {

                          //返回值非0，表示查找成功；返回值0，表示查找失败，不存在该编号
                           if( Node_GetIndexWithId( json_item->valuestring,  &uctmp ) )
                           {
                               Node_SetOnline( uctmp, 1 );
                               log_debug("OnlineInList mac=%s\n",json_item->valuestring );
                           }else{
                               log_debug("OnlineOutofList mac=%s\n",json_item->valuestring ); 
                           }
                    }

                }  // ---- if( json_item_array ) 
  
            }  //---for

	}

    log_debug("%s() end\n",__FUNCTION__);

	if (json) {
		cJSON_Delete(json);
	}


#endif

}




//---鸡肋-----实际上PLC开放性组网没办法区分是否是在白名单之内
////3.18  读非白名单在网设备 readOnlineNoList	38
void json_readback_readOnlineNoList(const char *pstr, const void *param)
{

#if 0


	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	cJSON *json_data_array = NULL;
	cJSON *json_item_array = NULL;

    int    json_data_array_size = 0, i = 0;
	unsigned int msg_id = 0;

    uint8_t  uctmp;

    int currFrame ;
    log_debug("%s() start\n",__FUNCTION__);


	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
        log_debug("not json string\n");
		return ;
	}

	msg_id = get_input_msgId(json);


  
     //文档是有data结构，实际测试没有
    // “data”: {               // 可选，用于指示分帧
    // “totalFrame”:2,          //如果白名单太长，可能要分帧， 没有此项，则为1帧。
    // “currFrame”:1,           // 第一帧
    // },

	// json_data = cJSON_GetObjectItem(json, "data");

	// if(json_data) {
        
   	// 	json_item = cJSON_GetObjectItem(json_data, "totalWhitelist" );
	// 	if(json_item) {
    //        // Node_SetNum( cJSON_GetNumberValue(json_item ) );
	// 	}
     
    // }



      //json_data = cJSON_GetObjectItem(json, "data");  //与文档描述不符----

           //"totalFrame":2,"currFrame":2,"totalWhitelist":17,
   		json_item = cJSON_GetObjectItem(json, "totalWhitelist" );
		if( json_item) {
           // Node_SetNum( cJSON_GetNumberValue(json_item ) );
            log_debug("totalWhitelist=%f\n",cJSON_GetNumberValue(json_item ));
		}

   		json_item = cJSON_GetObjectItem(json, "currFrame" );
		if( json_item) {
             currFrame = cJSON_GetNumberValue(json_item ) ;
             if(1== currFrame)
             {
                 Node_Clear( );  //ver "4.7" 
             }
              
            log_debug("currFrame=%d\n",currFrame );

		}

    log_debug("%s() end\n",__FUNCTION__);

	if (json) {
		cJSON_Delete(json);
	}

#endif


}







// 3.39  读取网关以太网ip信息  gwEthIpRead
// {
// “head”:{
//    "gatewayId":"gw_0000C0A80102",
// 。。。。。。
//        “cmd”:” gwEthIpRead”
// }
// }

// 应答：
// {
// “head”:{
//    "gatewayId":"gw_0000C0A80102",
// 。。。。。。
//        “response”:” gwEthIpRead”
// }
// “data”:{
//     “ip”:”192.168.1.120”,
//     “port”:12334,
//     “gateway”:”192.168.1.1”,
//     “mask”:”255.255.255.0”
// }
// }

// 3.39  读取网关以太网ip信息  gwEthIpRead
void json_readback_gwEthIpRead(const char *pstr, const void *param)
{
	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	unsigned int msg_id = 0;

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
		return ;
	}

	msg_id = get_input_msgId(json);

	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {
        
		json_item = cJSON_GetObjectItem(json_data, "ip" );
		if(json_item) {
              memset(gui_gw_param.eth0.ip,0,sizeof(gui_gw_param.eth0.ip) );
              strncpy(gui_gw_param.eth0.ip,json_item->valuestring,sizeof(gui_gw_param.eth0.ip) );
		}

		json_item = cJSON_GetObjectItem(json_data, "port" ); 
		if(json_item) {
             gui_gw_param.eth0.port = json_item->valueint;
		}


		json_item = cJSON_GetObjectItem(json_data, "gateway" );
		if(json_item) {
              memset(gui_gw_param.eth0.gateway,0,sizeof(gui_gw_param.eth0.gateway) );
              strncpy(gui_gw_param.eth0.gateway,json_item->valuestring,sizeof(gui_gw_param.eth0.gateway) );
		}


		json_item = cJSON_GetObjectItem(json_data, "mask" );
		if(json_item) {
              memset(gui_gw_param.eth0.mask,0,sizeof(gui_gw_param.eth0.mask) );
              strncpy(gui_gw_param.eth0.mask,json_item->valuestring,sizeof(gui_gw_param.eth0.mask) );
		}

	}


	if (json) {
		cJSON_Delete(json);
	}

	//int ret = 0 ; // .......  bind_set_json

	// response
	//response_server_comm("setGwTime",msg_id, ret, param);

}




#if 0

3.41  读取网关网络状态信息  gwIfconfigRead
{
“head”:{
   "gatewayId":"gw_0000C0A80102",
。。。。。。
       “cmd”:” gwIfconfigRead”
}
}

{
“head”:{
   "gatewayId":"gw_0000C0A80102",
。。。。。。
       “response”:” gwIfconfigRead”
}
“body”:[
{
 “netcard”:”eth0”,                   //   以太网
      “ip”:”192.168.1.120”,
     “port”:12334,
     “gateway”:”192.168.1.1”,
     “mask”:”255.255.255.0”
},
{
 “netcard”:”eth1”,              // eth1，此版本网关为4G 网卡
    “ip”:”192.168.5.120”,
    “port”:12334,
    “gateway”:”192.168.5.1”,
    “mask”:”255.255.255.0”
}
],
“data”:{
    “csq”:20,                      // 4G 信号强度
   “workNet”:”eth1”      //  使用4G 上网 。 “eth0”为以太网上网
}

}
#endif


//3.41  读取网关网络状态信息  gwIfconfigRead
void json_readback_gwIfconfigRead(const char *pstr, const void *param)
{
	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
//	cJSON *json_body = NULL;

    eth_info_t* peth =NULL;


	int i=0;
	unsigned int msg_id = 0;

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
		return ;
	}

	msg_id = get_input_msgId(json);

	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {
        
		json_item = cJSON_GetObjectItem(json_data, "workNet" );
		if(json_item) {
              memset(gui_gw_param.workNet,0,sizeof(gui_gw_param.workNet) );
              strncpy(gui_gw_param.workNet,json_item->valuestring,sizeof(gui_gw_param.workNet) );

		} 

		json_item = cJSON_GetObjectItem(json_data, "csq" ); 
		if(json_item) {
             gui_gw_param.csq = json_item->valueint;
		}

	}

// cJSON_GetArraySize(const cJSON *array);
// cJSON_GetArrayItem(const cJSON *array, int index);


	json_data = cJSON_GetObjectItem(json, "body");

	if(json_data) {
            
            int SUB_size = cJSON_GetArraySize(json_data);	//获取数组成员个数 

            for(i=0;i<SUB_size;i++)
            {
                cJSON * sub = cJSON_GetArrayItem(json_data,i);

                json_item = cJSON_GetObjectItem(sub, "netcard" );
                if(json_item) {
                    
                    if( 0==strcmp(json_item->valuestring,"eth0") )
                    {
                        peth = &gui_gw_param.eth0;
                    }else{
                        peth = &gui_gw_param.eth1;
                    }
                }

                json_item = cJSON_GetObjectItem(sub, "ip" );
                if(json_item) {
                    memset(peth->ip,0,sizeof(peth->ip) );
                    strncpy(peth->ip,json_item->valuestring,sizeof(peth->ip) );
                }


                json_item = cJSON_GetObjectItem(json_data, "port" ); 
                if(json_item) {
                    peth->port = json_item->valueint;
                }


                json_item = cJSON_GetObjectItem(json_data, "gateway" );
                if(json_item) {
                    memset(peth->gateway,0,sizeof(peth->gateway) );
                    strncpy(peth->gateway,json_item->valuestring,sizeof(peth->gateway) );
                }


                json_item = cJSON_GetObjectItem(json_data, "mask" );
                if(json_item) {
                    memset(peth->mask,0,sizeof(peth->mask) );
                    strncpy(peth->mask,json_item->valuestring,sizeof(peth->mask) );
                }

                //printf("%s ",cJSON_GetArrayItem(json_data,i)->valuestring);//解析数组中的字符串
            }//for

    }//if




	if (json) {
		cJSON_Delete(json);
	}

	
	//int ret = 0 ; // .......  bind_set_json

	// response
	//response_server_comm("setGwTime",msg_id, ret, param);


}






#if 0
// 3.32   读取主平台ip端口  mainIpRead
// {
// “head”:{
//    "gatewayId":"gw_0000C0A80102",
// 。。。。。。
//        “cmd”:” mainIpRead”
// }
// }


// 上行：
// {
// "head":{
// "gatewayId":"gw_0000C0A80102",
// 。。。。。
// "response":" mainIpRead "
// }，
// “data”: {
//     “ip”:”11.22.33.44”,
//    “port”:1234
// },

// “errCode”:0,
// “reason”:”xxxx”
// }
#endif



//3.32   读取主平台ip端口  mainIpRead
void json_readback_mainIpRead(const char *pstr, const void *param)
{
	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	unsigned int msg_id = 0;

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
		return ;
	}

	msg_id = get_input_msgId(json);

	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {
        
		json_item = cJSON_GetObjectItem(json_data, "ip" );
		if(json_item) {
              memset(gui_gw_param.ip_cfg.ip,0,sizeof(gui_gw_param.ip_cfg.ip) );
              strncpy(gui_gw_param.ip_cfg.ip,json_item->valuestring,sizeof(gui_gw_param.ip_cfg.ip) );
		}

		json_item = cJSON_GetObjectItem(json_data, "port" ); 
		if(json_item) {
             gui_gw_param.ip_cfg.port = json_item->valueint;
		}


	}


	if (json) {
		cJSON_Delete(json);
	}

	
	//int ret = 0 ; // .......  bind_set_json

	// response
	//response_server_comm("setGwTime",msg_id, ret, param);


}


// 3.35  读取网关io状态      gwIoRead
// 上行：
// {
// "head":{
// "gatewayId":"gw_0000C0A80102",
// 。。。。。
// "response":" gwIoRead "
// }，
// “data”: {
//     “input”:”13”,
//    “output”:”3”
// },

// “errCode”:0,
// “reason”:”xxxx”
// }

// input, output为hex字符串
// input : 13,  =0x13，  表示bit1，2，4 为高， 其他为低
// output ： 2， = 0x02 ， 表示bit1为高， 其他为低。


void json_readback_gwIoRead(const char *pstr, const void *param)
{


#if 0

	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;

	unsigned int msg_id = 0;

	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
		return ;
	}

	msg_id = get_input_msgId(json);


     //文档是有data结构，实际测试没有
    // “data”: {               // 可选，用于指示分帧
//     “input”:”13”,
//    “output”:”3”
    // },

// input : 13,  =0x13，  表示bit1，2，4 为高， 其他为低
// output ： 2， = 0x02 ， 表示bit1为高， 其他为低


	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {
        
   		json_item = cJSON_GetObjectItem(json_data, "input" );
		if(json_item) {
            bsp_op_decode( cJSON_GetNumberValue(json_item ) );
		}
     
   		json_item = cJSON_GetObjectItem(json_data, "output" );
		if(json_item) {
            bsp_relay_decode( cJSON_GetNumberValue(json_item ) );
		}

    }


	if (json) {
		cJSON_Delete(json);
	}	


#endif


}








/*
设置网关  setupGw
下行
{
   “head”:{
       ..........
       “cmd”:”setGwTime”
},
“data”:{
	“time”:12345678,     // unix时间
	“heartBeast”: 60      // 心跳周期，单位秒，0表示无需心跳
	}
}
上行
{
“head”:{
       ..........
       “response”:”setGwTime”
},
“errCode”:0,
“reason”:”xxxx”
}

	{"readGwMsg",        json_read_cmd},      ////3.14  读网关信息  readGwMsg	34
	{"readGwSetup",      json_read_cmd},      ////3.16  读网关配置 readGwSetup	36


void json_read_back_gwEthIpSet(const char *pstr, const void *param)
{
	cJSON *json;
	
	json = cJSON_Parse(pstr);
	if (json == NULL) { 	// not json string
		return ;
	}
//	cJSON *json_head;
	cJSON *json_item;
	cJSON *json_data = NULL;
	unsigned int msg_id = 0;
	msg_id = get_input_msgId(json);
	
	json_data = cJSON_GetObjectItem(json, "data");
	if(json_data) {
		json_item = cJSON_GetObjectItem(json_data, "time");
		if(json_data) {
			set_unix_time(json_item->valueint);
		}
		json_item = cJSON_GetObjectItem(json_data, "heartBeast");
		if(json_item) {
			set_heartbeast_time(json_item->valueint);
		}
		json_item = cJSON_GetObjectItem(json_data, "logMode");
		if(json_item) {
			set_log_mode(json_item->valueint);
		}
		commit_gw_status();
	}


	if (json) {
		cJSON_Delete(json);
	}

	
	int ret = 0 ; // .......  bind_set_json

	// response
	response_server_comm("setGwTime",msg_id, ret, param);
}

*/


 

/*
“head”:{
	  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
	  “msgId”:12345,           // 消息序列号
	  “timeStamp”:12345678,    // unix 时间
	  “notify”:”heartBeast”      // 指令类型
	},
*/
int set_json_comm_item(cJSON *root, const char *ptype, const char *pname, unsigned int msg_id)
{
	// time_t timeStamp;    
	// time(&timeStamp); //怎么用时间戳有问题
			
#if CJSON_TIME_STAMP_ENABLE
    time_t now_time_stamp;
    now_time_stamp = time(NULL);
    printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif

	cJSON *obj = cJSON_CreateObject();
    
    if( obj ==NULL)
    {
	  return 0;
    }


	cJSON_AddItemToObject(root, "head", obj);

	cJSON_AddStringToObject(obj, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(obj, "msgId", msg_id);

#if CJSON_TIME_STAMP_ENABLE

//	cJSON_AddNumberToObject(obj, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(obj, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............

	cJSON_AddNumberToObject(obj, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


	cJSON_AddStringToObject(obj, ptype, pname);

	return !0;
}



unsigned int get_input_msgId(const cJSON *json)
{
	cJSON *json_head;
	cJSON *json_item;
	unsigned int msg_id = -1;

	json_head = cJSON_GetObjectItem(json, "head");
	if(json_head) {
		json_item = cJSON_GetObjectItem(json_head, "msgId");
		if(json_item) {
			msg_id = json_item->valueint;
		}
	}

	return msg_id;
}





void json_write_cmd(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }


	cjs_body = cJSON_CreateObject();   //创建一个对象
    if (cjs_body == NULL)
    {
        goto lab_exit;
    }

#if CJSON_TIME_STAMP_ENABLE
    time_t now_time_stamp;
    now_time_stamp = time(NULL);
    printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif



//“head”:{
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	//添加字符串 
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );	//添加字符串 		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字

#if CJSON_TIME_STAMP_ENABLE
//	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	gui_js_api_timeStamp);
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif    

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif



    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	           
        goto lab_exit;
    }

#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}




void json_read_cmd(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;


	printf("%s,cmd=%s,id=%s\n",__FUNCTION__,cmd_str,cct_id_str);		//输出字符串


  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象


//“head”:{
////   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},


// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”

#if  0

	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字

#if CJSON_TIME_STAMP_ENABLE
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	gui_js_api_timeStamp);
#endif

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象

#else

	set_json_comm_item(cjs_root, TYPE_CMD, cmd_str, msg_id );  // gui_msg_id++

#endif




    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif





    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	           
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );


    //free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



/*------------------------------------------------------
3.5  读取分组 readGroup
每次读取一个分组的内容。
下行命令:
{
“head”:{
  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
  “msgId”:12345,           // 消息序列号
  “timeStamp”:12345678,    // unix 时间
  “cmd”:” readGroup”      // 
},
“data”:{
   “groupName”:”lunchGroup”,     //  name , addr 可以只传一个
   “addr”:203                    //
  }
}

-----------------------------------------------------*/


void json_read_cmd_readGroup(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象


//“head”:{
////   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},


#if CJSON_TIME_STAMP_ENABLE
time_t now_time_stamp;
now_time_stamp = time(NULL);
printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif

// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字


#if CJSON_TIME_STAMP_ENABLE
//	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	gui_js_api_timeStamp);
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);

#endif   

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象

//	set_json_comm_item(cjs_root, TYPE_CMD, cmd_str, 123456);



//“data”:{
//   “groupName”:”lunchGroup”,     //  name , addr 可以只传一个
//   “addr”:203                    //
//  }

	cJSON_AddStringToObject(cjs_data,	"groupName",	"lunchGroup" );	
	cJSON_AddNumberToObject(cjs_data,	"addr",	203);	//添加整型数字

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象




    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	           
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif		

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

    //free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}




//{"extenalSignal",    json_read_cmd},      ////3.22  外部信号输入 extenalSignal	41
/*------------------------------------------------------
3.22  外部信号输入 extenalSignal
主机向网关传送外接的lcd屏，zigbee传感器等的输入状态。
下行命令：
{
   “head”:{
       ..........
       “cmd”:”extenalSignal”,
   },
  “data”:
   {“deviceName”:”lcdPad1”,
    “pid”:”xxxxxxxx”
    “mac”:”112233445566”,
      “attr”:{        // 属性
        “keyHexString”:”00000005”    // 键0，2 按下（bit0=1，bit2=1）
  }
}
-----------------------------------------------------*/


void json_read_cmd_extenalSignal(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    cJSON* cjs_attr = NULL;	

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象


	cjs_attr = cJSON_CreateObject();   //创建一个对象
    if (cjs_attr == NULL)
    {
        goto lab_exit;
    }


    time_t now_time_stamp;
    now_time_stamp = time(NULL);
    printf("当前时间戳：%ld秒\n", now_time_stamp);
    



//“head”:{
////   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},


// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字


#if CJSON_TIME_STAMP_ENABLE
	//cJSON_AddNumberToObject(cjs_head,	"timeStamp",	gui_js_api_timeStamp);
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象



//“data”:{
//   {“deviceName”:”lcdPad1”,
//    “pid”:”xxxxxxxx”
//    “mac”:”112233445566”,
//      “attr”:{        // 属性
//        “keyHexString”:”00000005”    // 键0，2 按下（bit0=1，bit2=1）
//  }

	cJSON_AddStringToObject(cjs_data,	"deviceName",	"lcdPad1" );	
	cJSON_AddStringToObject(cjs_data,	"pid",	"xxxxxxxx" );	
	cJSON_AddStringToObject(cjs_data,	"mac",	"112233445566" );	

	cJSON_AddStringToObject(cjs_attr,	"keyHexString","00000005" );	  // 键0，2 按下（bit0=1，bit2=1）
	cJSON_AddItemToObject(cjs_data,	"attr",	cjs_attr );	//对象

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象
//	set_json_comm_item(cjs_root, TYPE_CMD, cmd_str, 123456);



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	            
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

    //free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



//	{"readPid",        json_read_cmd},      ///3.27 读取设备pid：   readPid    

/*------------------------------------------------------
3.27 读取设备pid：   readPid    
下行命令:
{
“head”:{
  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
  “msgId”:12345,           // 消息序列号
  “timeStamp”:12345678,    // unix 时间
  “cmd”:” readGroup”      // 
},
"data":{
“mac”:”112233445566”, 
“nodeType”:0, 
“channel”:1, 
“privAddr”:3
}

-----------------------------------------------------*/


void json_read_cmd_readPid(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象

#if CJSON_TIME_STAMP_ENABLE
time_t now_time_stamp;
now_time_stamp = time(NULL);
printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif

//“head”:{
////   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},


// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字

#if CJSON_TIME_STAMP_ENABLE
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象




//"data":{
//“mac”:”112233445566”, 
//“nodeType”:0, 
//“channel”:1, 
//“privAddr”:3
//}
	cJSON_AddStringToObject(cjs_data,	"mac",	"112233445566" );	
	cJSON_AddNumberToObject(cjs_data,	"nodeType",	0);	//
	cJSON_AddNumberToObject(cjs_data,	"channel",	1);	//
	cJSON_AddNumberToObject(cjs_data,	"privAddr",	3);	//


	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	          
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

//    free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



//	{"syncScene",       json_read_cmd},      ////3.28  同步场景数据   syncScene	44

/*------------------------------------------------------
3.28  同步场景数据   syncScene
下行命令:
{
“head”:{
  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
  “msgId”:12345,           // 消息序列号
  “timeStamp”:12345678,    // unix 时间
  “cmd”:” syncScene      // 
},
“data”:{
      “level”:1,      //   1~4
     “discr”:” forceSyncAll”,
     “opName”:”lunch”,     // 由level 决定
}
-----------------------------------------------------*/


void json_read_cmd_syncScene(const char* cmd_str,const char* cct_id_str,const int msg_id )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }

    #if CJSON_TIME_STAMP_ENABLE
    time_t now_time_stamp;
    now_time_stamp = time(NULL);
    printf("当前时间戳：%ld秒\n", now_time_stamp);
   #endif 


//	cjs_body = cJSON_CreateObject();   //创建一个对象


//“head”:{
////   “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},


// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字

#if CJSON_TIME_STAMP_ENABLE
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象



//“data”:{
//      “level”:1,      //   1~4
//     “discr”:” forceSyncAll”,
//     “opName”:”lunch”,     // 由level 决定
//}

	cJSON_AddNumberToObject(cjs_data,	"level",	1);	// 1~4
	cJSON_AddStringToObject(cjs_data,	"discr",	"forceSyncAll");	
	cJSON_AddStringToObject(cjs_data,	"opName",	"lunch" );	 // 由level 决定


	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	           
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
     //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



/*----------------------------------------

3.12  读属性  readAttr
可以读单个设备属性，也可以读群组属性。群组属性应答是分别包含全部群组内设备的属性。因群组设备属性可能被单独修改过。

3.12.1读单个设备属性
下行：
{
   “head”:{
       ..........
       “cmd”:”readAttr”
},
“data”: { 
    “deviceName”:”lamp1”,
}
}

上行：
{
   “head”:{
       ..........
       “response”:”readAttr”
},
“data”: {
  “deviceName”:”lamp1”,
  “mac”:”112233445566”,
“nodeType”:0,
           “channel”:1,
           “privAddr”:23,

  "pid": "xxxxx1",
“attr”:{
       “power”:1,
       “bright”:80,
       “cct”:3000
}
},
“errCode”:0,
“reason”:”xxxx”
}

------------------------------------------------------------------*/

//----读属性--------single
//----读单个属性--------
void json_read_cmd_readAttr_Single(const char* cmd_str,const char* cct_id_str,const int msg_id ,const char* deviceName_str  )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象


//“head”:{
//  “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”readAttr”      // 指令类型为：cmd
//},

#if CJSON_TIME_STAMP_ENABLE
time_t now_time_stamp;
now_time_stamp = time(NULL);
printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif




// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

	cJSON_AddStringToObject(cjs_head,	"cmd",	cmd_str );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	msg_id );	//添加整型数字
//	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++);	//添加整型数字

#if CJSON_TIME_STAMP_ENABLE
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif

	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象


// “data”: { 
//     “deviceName”:”lamp1”,
// }

	cJSON_AddStringToObject(cjs_data,	"“deviceName”",	deviceName_str);

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
      	printf("cJSON_Print error!\n");	          
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}





void json_read_RS485_meter_name(void)
{
   json_read_cmd_readAttr_Single( "readWhiteList", get_gateway_id() ,gui_js_api_msg_id++,RS485_METER_DEVC_NAME);

}





// 读取外接电表数据
void json_read_RS485_meter(const char* cct_id_str,const MeterConfig_st* meter )
{

  cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;	
 //   cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//	cjs_body = cJSON_CreateObject();   //创建一个对象


//“head”:{
//  “replaceId”:”gw_000011112222”,  // 消息目的地/消息来源地 识别码	
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”readAttr”      // 指令类型为：cmd
//},

#if CJSON_TIME_STAMP_ENABLE
time_t now_time_stamp;
now_time_stamp = time(NULL);
printf("当前时间戳：%ld秒\n", now_time_stamp);
#endif

// 组播则是分类发送，有 platform， mobile（小程序或app），panel（中控屏）3类。
//replaceId	平台	手机	面板
//字符串	“platform”	“mobile”	“panel”


	cJSON_AddStringToObject(cjs_head,	"replaceId",	"panel" );	

//	cJSON_AddStringToObject(cjs_head,	"cmd",	"readGwMsg" );	
	cJSON_AddStringToObject(cjs_head,	"cmd",	"readAttr" );		
	cJSON_AddStringToObject(cjs_head,	"gatewayId",	cct_id_str );	//添加字符串 

	cJSON_AddNumberToObject(cjs_head,	"msgId",	gui_js_api_msg_id++ );	//添加整型数字

 #if CJSON_TIME_STAMP_ENABLE
	cJSON_AddNumberToObject(cjs_head,	"timeStamp",	now_time_stamp);
#endif
	cJSON_AddItemToObject(cjs_root,	"head",	cjs_head );	//对象


// "data": {
// 	"deviceName": "dev050",
// 	"mac": "FFFFFFFFFFFF",
// 	"nodeType": 1,
// 	"channel": 1,
// 	"privAddr": 50,
// 	"pid": "2003"
// },
   

	cJSON_AddStringToObject(cjs_data,	"deviceName",	meter->deviceName);
	cJSON_AddStringToObject(cjs_data,	"mac",	RS485_METER_BROADCAST_MAC_STR );    
	cJSON_AddNumberToObject(cjs_data,	"nodeType",	meter->nodeType );	//添加整型数字
	cJSON_AddNumberToObject(cjs_data,	"channel",	meter->channel  );	
	cJSON_AddNumberToObject(cjs_data,	"privAddr",	meter->privAddr );	
 	cJSON_AddStringToObject(cjs_data,	"pid",	meter->pid );     //----PID_RS485_METER_STR

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif



    if (cjs_str == NULL)
    {
 	    printf("cJSON_Print error!\n");	       
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}


 //  json_readback_RS485_meter

 //----readAttr-----
void json_readback_readAttr(const char *pstr, const void *param)
{
	cJSON *json = NULL;
//	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_data = NULL;
	cJSON *json_data_array = NULL;
	cJSON *json_item_array = NULL;

	cJSON *json_item_1 = NULL;

    int    json_data_array_size = 0, i = 0;
	unsigned int msg_id = 0;

   // uint8_t  uctmp;
   // NodeCore_st  node_core;

     MeterConfig_st   meter_cfg;

    log_debug("%s() start\n", __FUNCTION__ );

// {"head":{"gatewayId":"gw_1C32830600F4","replaceId":"gw_1712733707430","msgId":0,"timeStamp":1712741336,"response":"readAttr"},
	json = cJSON_Parse(pstr);
	if (json == NULL) { // not json string
        log_debug("not json string\n");
		return ;
	}

	msg_id = get_input_msgId(json);

    memset(&meter_cfg,0,sizeof(MeterConfig_st) );

// "data":{"nodeType":1,"channel":1,"privAddr":50,"mac":"FFFFFFFFFFFF","name":"dev050","pid":"2003","totalFrame":2,"currFrame":1,"totalAttr":52,"itemCnt":40},

	json_data = cJSON_GetObjectItem(json, "data");

	if(json_data) {   //data 
        
   		json_item = cJSON_GetObjectItem(json_data, "nodeType" );
		if(json_item) {
           meter_cfg.nodeType = cJSON_GetNumberValue(json_item);      
           log_debug(" meter_cfg.nodeType=%d\n", meter_cfg.nodeType );

		}


   		json_item = cJSON_GetObjectItem(json_data, "channel" );
		if(json_item) {
           meter_cfg.channel = cJSON_GetNumberValue(json_item);      
           log_debug(" meter_cfg.channel=%d\n", meter_cfg.channel );

		}

   		json_item = cJSON_GetObjectItem(json_data, "privAddr" );
		if(json_item) {
           meter_cfg.privAddr = cJSON_GetNumberValue(json_item);      
           log_debug(" meter_cfg.privAddr=%d\n", meter_cfg.privAddr );

		}


        //--发送与接收的对象名称不一样
   		json_item = cJSON_GetObjectItem(json_data, "name" );
		if(json_item) {
           
           memset(meter_cfg.deviceName,0,0);
           strcpy(meter_cfg.deviceName ,cJSON_GetStringValue(json_item) ) ;     

           log_debug(" meter_cfg.deviceName=%s\n", meter_cfg.deviceName );

		}

   		json_item = cJSON_GetObjectItem(json_data, "pid" );
		if(json_item) {
           
           memset(meter_cfg.pid,0,0);
           strcpy(meter_cfg.pid ,cJSON_GetStringValue(json_item) ) ;     

           log_debug(" meter_cfg.pid=%s\n", meter_cfg.pid );

		}

    }


//-------根据-不同的pid 解析不同的节点数据------------------------------------
//比较两个电表是否匹配  相等返回>0;不相等返回0，出错返回<0
   if(  Meter_is_pid_eq(&meter_cfg , &meter_config) <= 0 )
   { //不相同的话就电表不匹配
        goto lab_exit;
   }



//"attrLst":[
// {"name":"pt","lable":"电压变比","val":1},
// {"name":"ct","lable":"电流变比","val":1},


	json_data_array = cJSON_GetObjectItem(json, "attrLst");

	if( json_data_array ) {      

       json_data_array_size = cJSON_GetArraySize(json_data_array);
       log_debug("json_data_array_size=%d\n",json_data_array_size);


            for(i = 0; i < json_data_array_size; i++)
            {
                json_item_array = cJSON_GetArrayItem(json_data_array, i);

                if( json_item_array ) 
                {

                     json_item = cJSON_GetObjectItem(json_item_array, "name" );

                    if(json_item) {

                         if(  0== strcmp("pt", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.VT  = cJSON_GetNumberValue(json_item_1); // "lable":"电压变比"
                                   log_debug("VT=%d\n", MeterData.VT );

                                }

                         }


                         if(  0== strcmp("ct", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.CT  = cJSON_GetNumberValue(json_item_1); // "lable":"电流变比"
                                   log_debug("CT=%d\n", MeterData.CT );

                                }
                         }


// {"name":"volt_a","lable":"A相电压","val":2321},
// {"name":"volt_b","lable":"B相电压","val":2321},
// {"name":"volt_c","lable":"C相电压","val":2321},

                         if(  0== strcmp("volt_a", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Urms_A  = cJSON_GetNumberValue(json_item_1);   //A相电压
                                   log_debug("Urms_A=%d\n", MeterData.Urms_A );

                                }

                         }


                         if(  0== strcmp("volt_b", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Urms_B  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Urms_B=%d\n", MeterData.Urms_B );
                                }

                         }

                         if(  0== strcmp("volt_c", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Urms_C  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Urms_C=%d\n", MeterData.Urms_C );

                                }

                         }


// {"name":"curr_a","lable":"A相电流","val":0},
// {"name":"curr_b","lable":"B相电流","val":0},
// {"name":"curr_c","lable":"C相电流","val":0},
//"name":"currVectorSum","lable":"3相电流矢量和","val":0},


                         if(  0== strcmp("curr_a", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Irms_A  = cJSON_GetNumberValue(json_item_1);   //A相电流
                                   log_debug("Irms_A=%d\n", MeterData.Irms_A );

                                }

                         }


                         if(  0== strcmp("curr_b", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Irms_B  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Irms_B=%d\n", MeterData.Irms_B );

                                }

                         }

                         if(  0== strcmp("curr_c", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Irms_C  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Irms_C=%d\n", MeterData.Irms_C );

                                }

                         }


#if 0
                         if(  0== strcmp("currVectorSum", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Irms_T = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Irms_T=%d\n", MeterData.Irms_T );

                                }

                         }

#endif


// {"name":"active_pwr_a","lable":"A相有功功率","val":0},
// {"name":"active_pwr_b","lable":"B相有功功率","val":0},
// {"name":"active_pwr_c","lable":"C相有功功率","val":0},
// {"name":"active_pwr_total","lable":"总有功功率","val":0},

                         if(  0== strcmp("active_pwr_a", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Power_A  = cJSON_GetNumberValue(json_item_1);   //A相电压
                                   log_debug("Power_A=%d\n", MeterData.Power_A );

                                }

                         }


                         if(  0== strcmp("active_pwr_b", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Power_B  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Power_B=%d\n", MeterData.Power_B );

                                }

                         }

                         if(  0== strcmp("active_pwr_c", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Power_C  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Power_C=%d\n", MeterData.Power_C );

                                }

                         }



                         if(  0== strcmp("active_pwr_total", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Power_T = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Power_T=%d\n", MeterData.Power_T );

                                }

                         }


// {"name":"pf_a","lable":"A相功率因素","val":100},
// {"name":"pf_b","lable":"B相功率因素","val":100},
// {"name":"pf_c","lable":"C相功率因素","val":100},
// {"name":"pf_total","lable":"总功率因素","val":100},


                         if(  0== strcmp("pf_a", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.PF_A  = cJSON_GetNumberValue(json_item_1);   //A相电压
                                   log_debug("PF_A=%d\n", MeterData.PF_A );

                                }

                         }


                         if(  0== strcmp("pf_b", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.PF_B  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("PF_B=%d\n", MeterData.PF_B );

                                }

                         }

                         if(  0== strcmp("pf_c", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.PF_C  = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("PF_C=%d\n", MeterData.PF_C );

                                }

                         }



                         if(  0== strcmp("pf_total", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.PF_T = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("PF_T=%d\n", MeterData.PF_T );

                                }

                         }


    // {"name":"active_engi_total","lable":"组合有功总电能","val":1941},
    // {"name":"forwoadActiveEnergy","lable":"正向有功电能","val":1935},
    // {"name":"backwardActiveEnergy","lable":"反向有功电能","val":60},
    // {"name":"forwoadReactiveEnergy","lable":"正向无功电能","val":134},
    // {"name":"backwardReactiveEnergy","lable":"反向无功电能","val":


                         if(  0== strcmp("active_engi_total", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.EnergyP  = cJSON_GetNumberValue(json_item_1);   //组合有功总电能
                                   log_debug("EnergyP=%d\n", MeterData.EnergyP );

                                }

                         }



//{"name":"freq","lable":"频率","val":5003},

                         if(  0== strcmp("freq", cJSON_GetStringValue(json_item) ) )
                         {//为0表示相等

                            json_item_1 = cJSON_GetObjectItem(json_item_array, "val" );

                            if(json_item_1) {
                                   MeterData.Freq = cJSON_GetNumberValue(json_item_1); 
                                   log_debug("Freq=%d\n", MeterData.Freq );

                                }

                         }


                    }  // if(json_item) {


                }  // ---- if( json_item_array ) 
  
            }  //---for

	}////-----if( json_data_array ) {  



    log_debug("%s()cjs_root end\n",__FUNCTION__);


lab_exit:

    if ( json != NULL)        //      
    {
	    cJSON_Delete(json);		//清除结构体
    }

    json = NULL;  



}







//3.2  读取白名单  readWhiteList
void json_readWhiteList(void)
{
   //Node_Clear( );  // 不能在这里--否则显示无节点
   json_read_cmd( "readWhiteList", get_gateway_id() ,gui_js_api_msg_id++);

}


//3.4  读取分组名称数量 readGroupNameNum 
void json_readGroupNameNum (void)
{
   json_read_cmd( "readGroupNameNum", get_gateway_id() ,gui_js_api_msg_id++);
}


//3.5  读取分组 readGroup	16
void json_readGroup(void)
{
   //json_read_cmd_with_data( "readGroup", get_gateway_id() ,gui_js_api_msg_id++);
}




//3.16  读网关配置 readGwSetup	36
void json_readGwSetup (void)
{
   json_read_cmd( "readGwSetup", get_gateway_id() ,gui_js_api_msg_id++);
}

///3.17  读白名单在网设备 readOnlineInList	37
void json_readOnlineInList (void)
{
   json_read_cmd( "readOnlineInList", get_gateway_id() ,gui_js_api_msg_id++);
}

//3.18  读非白名单在网设备 readOnlineNoList	38
void json_readOnlineNoList(void)
{
   json_read_cmd( "readOnlineNoList", get_gateway_id() ,gui_js_api_msg_id++);
}



//3.20  重启网关  resetGw
void json_resetGw( void )
{
   json_read_cmd( "resetGw", get_gateway_id() ,gui_js_api_msg_id++);
}


/*
3.27 读取设备pid：   readPid
下行：
{"head":
{"gatewayId":"gw_0000C0A80102","cmd":"readPid"},
"data":{
“mac”:”112233445566”, 
“nodeType”:0, 
“channel”:1, 
“privAddr”:3
}
}
*/


//3.27 读取设备pid
void json_readPid(void)
{
   json_read_cmd( "readPid", get_gateway_id() ,gui_js_api_msg_id++);
}




//3.32   读取主平台ip端口  mainIpRead	47
void json_mainIpRead(void)
{
   json_read_cmd( "mainIpRead", get_gateway_id() ,gui_js_api_msg_id++);
}



//读电表数据
void json_meterRead(void)
{
   json_read_cmd( "mainIpRead", get_gateway_id() ,gui_js_api_msg_id++);
}

#if  0
{"head":{"gatewayId":"gw_1C32830600F4","replaceId":"gw_1712733707430","msgId":0,"timeStamp":1712741336,"response":"readAttr"},
"data":{"nodeType":1,"channel":1,"privAddr":50,"mac":"FFFFFFFFFFFF","name":"dev050","pid":"2003","totalFrame":2,"currFrame":1,"totalAttr":52,"itemCnt":40},
"attrLst":[{"name":"pt","lable":"电压变比","val":1},{"name":"ct","lable":"电流变比","val":1},{"name":"tempeN","lable":"N相温度","val":0},{"name":"dataTime",
"lable":"日期时间","str":""},{"name":"volt_a","lable":"A相电压","val":2321},{"name":"volt_b","lable":"B相电压","val":2321},
{"name":"volt_c","lable":"C相电压","val":2321},{"name":"voltab","lable":"AB线电压","val":4020},{"name":"voltbc","lable":"BC线电压","val":4020},
{"name":"voltca","lable":"CA线电压","val":4020},{"name":"curr_a","lable":"A相电流","val":0},{"name":"curr_b","lable":"B相电流","val":0},
{"name":"curr_c","lable":"C相电流","val":0},{"name":"currVectorSum","lable":"3相电流矢量和","val":0},{"name":"active_pwr_a","lable":"A相有功功率","val":0},
{"name":"active_pwr_b","lable":"B相有功功率","val":0},{"name":"active_pwr_c","lable":"C相有功功率","val":0},
{"name":"active_pwr_total","lable":"总有功功率","val":0},{"name":"reactive_pwr_a","lable":"A相无功功率","val":0},
{"name":"reactive_pwr_b","lable":"B相无功功率","val":0},{"name":"reactive_pwr_c","lable":"C相无功功率","val":0},
{"name":"reactive_pwr_total","lable":"总无功功率","val":0},{"name":"apparent_pwr_a","lable":"A相是在功率","val":0},
{"name":"apparent_pwr_b","lable":"B相视在功率","val":0},{"name":"apparent_pwr_c","lable":"C相视在功率","val":0},
{"name":"apparent_pwr_total","lable":"总视在功率","val":0},{"name":"pf_a","lable":"A相功率因素","val":100},
{"name":"pf_b","lable":"B相功率因素","val":100},{"name":"pf_c","lable":"C相功率因素","val":100},
{"name":"pf_total","lable":"总功率因素","val":100},{"name":"di","lable":"di状态","val":0},{"name":"freq","lable":"频率","val":5003},
{"name":"active_engi_total","lable":"组合有功总电能","val":1941},{"name":"forwoadActiveEnergy","lable":"正向有功电能","val":1935},
{"name":"backwardActiveEnergy","lable":"反向有功电能","val":60},{"name":"forwoadReactiveEnergy","lable":"正向无功电能","val":134},
{"name":"backwardReactiveEnergy","lable":"反向无功电能","val":


#endif  





//--------write cmd----------------------------

/*----------------------------------------------------------------------------------------
当前实现的命令

3.7  配置场景  setScence	18
3.9  配置绑定  setBind	21
3.15  设置网关  setupGw	35
3.20  重启网关  resetGw	40
3.22  外部信号输入 extenalSignal	41
3.33  设置主平台ip端口   mainIpSet	47

3.36  设置网关io（继电器） 状态  gwIoSet	49
3.36.1   全部output同时设	49
3.36.2    指定设置某个或某几个output	49
3.40  设置网关以太网ip信息  gwEthIpSet	52
-------------------------------------------------------------------------------------------------------------------------------- */



//3.33  设置主平台ip端口   mainIpSet

// {
// "head":{
// "gatewayId":"gw_0000C0A80102",
// 。。。。。
// "cmd":" mainIpSet"
// }，
// “data”: {
//     “ip”:”11.22.33.44”,
//    “port”:1234
// }
// }



void json_write_mainIpSet(const char* ip_str ,const int port  )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_data = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//“head”:{
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},

	if(  0==set_json_comm_item(cjs_root, TYPE_CMD, "mainIpSet", gui_js_api_msg_id++) )
    {
        goto lab_exit;     
    }



// “data”: {
//    “ip”:”11.22.33.44”,
//    “port”:1234
// }
// }

	cJSON_AddStringToObject(cjs_data,	"ip",	ip_str );	
	cJSON_AddNumberToObject(cjs_data,	"port",port );

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象




    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
     	printf("cJSON_Print error!\n");	           
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

//    free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}




//3.36  设置网关io（继电器） 状态  gwIoSet	49

void json_write_gwIoSet(const char* ouput_data )  //  const int ouput_data  )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_data = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


//“head”:{
//  “gatewayId”:”xxxxxx”,      // 消息来源或目的设备
//  “msgId”:12345,           // 消息序列号
//  “timeStamp”:12345678,    // unix 时间
//  “cmd”:”setWhiteList”      // 指令类型为：cmd
//},

	if(  0==set_json_comm_item(cjs_root, TYPE_CMD, "gwIoSet", gui_js_api_msg_id++) )      /////--=----msg_id
    {
        goto lab_exit;     
    }

// “data”: {
//     “output”:”a”   //?????是字符串还是整型 
// }
// }
//Output : a, = 0x0a,  表示 bit1， bit3 输出高， bit0，bit2输出低 


	cJSON_AddStringToObject(cjs_data,	"output",	ouput_data );	
//	cJSON_AddNumberToObject(cjs_data,	"output",	ouput_data );	

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif





    if (cjs_str == NULL)
    {
      	printf("cJSON_Print error!\n");	          
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



//3.40  设置网关以太网ip信息  gwEthIpSet	52
// “data”:{
//     “ip”:”192.168.1.120”,
//     “port”:12334,
//     “gateway”:”192.168.1.1”,
//     “mask”:”255.255.255.0”
// }
// }


void json_write_gwEthIpSet(const char* ip_str ,const int port ,const char* gateway_str , const char* mask_str )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_data = NULL;

    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_data = cJSON_CreateObject();   //创建一个对象
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }

	if(  0==set_json_comm_item(cjs_root, TYPE_CMD, "gwEthIpSet", gui_js_api_msg_id++) )
    {
        goto lab_exit;     
    }
	cJSON_AddStringToObject(cjs_data,	"ip",	ip_str );	
	cJSON_AddNumberToObject(cjs_data,	"port",port );
	cJSON_AddStringToObject(cjs_data,	"gateway",gateway_str );
 	cJSON_AddStringToObject(cjs_data,	"mask",	mask_str );   

	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif


    if (cjs_str == NULL)
    {
       	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据
    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );

//    free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}






// 本地广播控制 ====需要新增页面----广播关0%--广播开100%--广播50%---
// 2.2  广播调光
// {
// 	"data": {
// 		"mac": "FFFFFFFFFFFF",
// 		"pid": "1111",    ///需要明确指定pid
// 		"attr": {
// 			"bright": 24    //亮度
// 		}
// 	},
// 	"head": {
// 		"gatewayId": "gw_0000C0A8011B",
// 		"msgId": 0,
// 		"timeStamp": 0,
// 		"cmd": "setAttr"
// 	}
// }
#if 0
{
        "head": {
                "gatewayId":    "gw_0000C0A80101",
                "msgId":        123456,
                "timeStamp":    1720158644,
                "cmd":  "setAttr"
        },
        "data": {
                "mac":  "FFFFFFFFFFFF",
                "pid":  "1111",
                "attr": {
                        "bright":       100
                }
        }
}



#endif



void json_write_setAttr(const char* node_mac ,const char* pid_str ,const uint8_t power ,const uint8_t bright , const char* name_str )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_data = NULL;
    cJSON* cjs_item = NULL;
    char*  cjs_str  = NULL;

  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_data = cJSON_CreateObject();   //创建一个对象data
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }

	if(  0==set_json_comm_item(cjs_root, TYPE_CMD, "setAttr", gui_js_api_msg_id++) )
    {
        goto lab_exit;     
    }

// 	"data": {
// 		"mac": "FFFFFFFFFFFF",
// 		"pid": "1111",    ///需要明确指定pid
// 		"attr": {
// 			"bright": 24    //亮度
// 		}
// 	},


    if(NULL !=node_mac)
    {
        cJSON_AddStringToObject(cjs_data,	"mac",	node_mac );
    }
	
	
    if(NULL !=name_str)
    {
        cJSON_AddStringToObject(cjs_data,	"name",	name_str );
    }
	

    if(NULL !=pid_str)
    {
        cJSON_AddStringToObject(cjs_data,	"pid",	pid_str );
    }
	



	cjs_item = cJSON_CreateObject();   //创建一个对象  attr
    if (cjs_item == NULL)
    {
        goto lab_exit;
    }


     cJSON_AddNumberToObject(cjs_item,	"bright",	bright );
     cJSON_AddNumberToObject(cjs_item,	"power",	power );    


     cJSON_AddItemToObject(cjs_data,	"attr",	cjs_item );


	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif


    if (cjs_str == NULL)
    {
      	printf("cJSON_Print error!\n");	          
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );


 //   free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}






// 亮度条（bright）（范围0~100）
// 色温条（cct）（范围暂时定为2700 ~6500，  最大值和最小值可能以后需要允许用户
//   W = bright * (cct – MIN_CCT)/(MAX_CCT-MIN_CCT) = bright * (cct-2700)/3800
//   C = bright – W 
#define   CCT_BAR_MIN       (2700)
#define   CCT_BAR_MAX       (6500)

//返回0失败，!0成功
uint8_t get_bright_wc_double(uint8_t bright ,const uint16_t cct , double* bright_c , double* bright_w )
{

 double w,c;


   if( (cct < CCT_BAR_MIN) || (cct > CCT_BAR_MAX) )
   {
      return 0;
   }


   if( bright > 100 )
   {
      bright = 100;
   }
   
   w =  (cct - CCT_BAR_MIN); 
   w /= (CCT_BAR_MAX -CCT_BAR_MIN);
   w *= bright;
   
   c = bright - w;

   *bright_w = w;
   *bright_c = c;

  printf("bright_c=%f, bright_w=%f\n",c,w);

return 1;

}


//返回0失败，!0成功
uint8_t get_bright_wc_int(uint8_t bright ,const uint16_t cct , int* bright_c , int* bright_w )
{
 int w,c;

   if( (cct < CCT_BAR_MIN) || (cct > CCT_BAR_MAX) )
   {
      return 0;
   }


   if( bright > 100 )
   {
      bright = 100;
   }
   
   w =  (cct - CCT_BAR_MIN)*100; //不乘以100，w会一直为0
   w /= (CCT_BAR_MAX -CCT_BAR_MIN);
   w *= bright;
   w /=100;

   c = bright - w;

   *bright_w = w;
   *bright_c = c;


 // printf("bright_c=%d, bright_w=%d\n",c,w);


return 1;

}



//双色灯
// {
// 	"data": {
// 		"pid": "1313",
// 		"mac": "FFFFFFFFFFFF",
// 	},
// 	"attrLst": [{
// 		"name": "W",
// 		"type": 0,
// 		"val": 21
// 	}, {
// 		"name": "C",
// 		"type": 0,
// 		"val": 58
// 	}],
// 	"head": {
// 		"gatewayId": "gw_0000C0A8011B",
// 		"msgId": 0,
// 		"timeStamp": 0,
// 		"cmd": "setAttr",
// 		"appuserId": 11
// 	}
// }

//广播双色温调光
void json_write_double_color_lamp(const char* node_mac ,const char* pid_str ,const uint8_t bright)
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_data = NULL;
    char*  cjs_str  = NULL;


 //double bright_c , bright_w ;
 int bright_c , bright_w ;

  printf("%s\n",__FUNCTION__);


//返回0失败，!0成功
   if( !get_bright_wc_int( bright ,(CCT_BAR_MAX +CCT_BAR_MIN)/2 ,  &bright_c ,  &bright_w ) )
   {
       printf("get_bright_wc_int error\n");

       goto lab_exit;
   }


  // char gatewayId_str[]="010000000780";
	
	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_data = cJSON_CreateObject();   //创建一个对象data
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }

	if(  !set_json_comm_item(cjs_root, TYPE_CMD, "setAttr", gui_js_api_msg_id++) )
    {
        printf("set_json_comm_item error\n");       
        goto lab_exit;     
    }


// 	"data": {
// 		"pid": "1313",
// 		"mac": "FFFFFFFFFFFF",
// 	},
	// "attrLst": [{
	// 	"name": "W",
	// 	"type": 0,  // val 的类型， 0：整数，1：布尔， 2：浮点数 ， 默认整数 
	// 	"val": 21
	// }, {
	// 	"name": "C",
	// 	"type": 0,
	// 	"val": 58
	// }],




    if(NULL !=node_mac)
    {
        cJSON_AddStringToObject(cjs_data,	"mac",	node_mac );
    }
	

    if(NULL !=pid_str)
    {
        cJSON_AddStringToObject(cjs_data,	"pid",	pid_str );
    }


	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//添加数组对象到跟对象



	cJSON *cjs_attrLst  = cJSON_CreateArray();				//创建一个数组  cjs_attrLst

    if (cjs_attrLst == NULL)
    {
        goto lab_exit;
    }


	cJSON* cjs_lamp_w = cJSON_CreateObject();   //创建一个对象  
    if (cjs_lamp_w == NULL)
    {
        goto lab_exit;
    }


	cJSON* cjs_lamp_c = cJSON_CreateObject();   //创建一个对象  
    if (cjs_lamp_c == NULL)
    {
        goto lab_exit;
    }


	// 	"name": "W",
	// 	"type": 0,  // val 的类型， 0：整数，1：布尔， 2：浮点数 ， 默认整数 
	// 	"val": 21
	// },

	 cJSON_AddStringToObject(cjs_lamp_w,	"name",	"W");		//添加字符串 
     cJSON_AddNumberToObject(cjs_lamp_w,	"type",	0 );       // val 的类型， 0：整数，1：布尔， 2：浮点数 ， 默认整数 
     cJSON_AddNumberToObject(cjs_lamp_w,	"val",	bright_w );

     cJSON_AddItemToArray(cjs_attrLst,	cjs_lamp_w );	//添加对象到数组中


	 cJSON_AddStringToObject(cjs_lamp_c,	"name",	"C");		//添加字符串 
     cJSON_AddNumberToObject(cjs_lamp_c,	"type",	0 );       // val 的类型， 0：整数，1：布尔， 2：浮点数 ， 默认整数 
     cJSON_AddNumberToObject(cjs_lamp_c,	"val",	bright_c );

     cJSON_AddItemToArray(cjs_attrLst,	cjs_lamp_c );	//添加对象到数组中


	cJSON_AddItemToObject(cjs_root,	"attrLst",	cjs_attrLst );	//添加数组对象到跟对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif





    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}










// 本地广播控制 ====需要新增页面----广播关0%--广播开100%--广播50%---
// 2.2  广播调光
// DEV_TYPE_ROADLAMP = 0x1111,           // 路灯
// DEV_TYPE_ROADLAMP_2COLOR = 0x1212, 		  // 路灯 2色
// DEV_TYPE_ROADLAMP_5COLOR = 0x1215,		  // 路灯 5色
	// DEV_TYPE_ROADLAMP = 0x1111,           // 路灯
	// DEV_TYPE_ROADLAMP_DOUBLE = 0x1313,    // 双色路灯

//power:0 单色灯,power:1 双色灯
void json_write_cmd_broadcast_dim(const char* pid_str ,const uint8_t power ,const uint8_t bright  )
{

  if( POWER_ROADLAMP_DOUBLE==power )
  {
    //广播双色温调光
      json_write_double_color_lamp("FFFFFFFFFFFF", pid_str , bright);

  }else{  //POWER_ROADLAMP
     json_write_setAttr( "FFFFFFFFFFFF", pid_str , power,bright ,NULL );  //DEV_TYPE_ROADLAMP
  }  


}





// {
// 	"head": {
// 		"gatewayId": "gw_1C32830600E4",
// 		"cmd": "setWhiteList"
// 	},
// 	"body": [{
// 		"name": "bk1",
// 		"mac": "FFFFFFFFFFFF",
// 		"pid": "D001",
// 		"nodeType": 1,
// 		"channel": 2,
// 		"privAddr": 17
// 	}]
// }


/////num 不能超过16个
void json_write_cmd_set_white_list_more(dev_mod_info_t* info,iot_node_dev_type_e* iot_type,uint8_t num)
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
  //  cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

   char iot_type_str[16]="";
   char dev_name_str[64]="";
   //char type_name_str[32]="";  
   
 #define  MAX_CJS_DATA_LENGTH (16U)  
cJSON* cjs_data[MAX_CJS_DATA_LENGTH];


uint8_t  cnt; //cjs_cnt

   if(NULL ==info)
   {
     return;
   }

   if(num>=MAX_CJS_DATA_LENGTH)
   {
     return;
   }


	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }

	cjs_head = cJSON_CreateObject();   //创建一个对象data
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cJSON_AddItemToObject(cjs_root, "head", cjs_head);

	cJSON_AddStringToObject(cjs_head, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(cjs_head, "msgId", gui_js_api_msg_id++);

#if CJSON_TIME_STAMP_ENABLE

    //cJSON_AddNumberToObject(cjs_head, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(cjs_head, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............
	cJSON_AddNumberToObject(cjs_head, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


    // “cmd”:”delWhiteList”,
    // “passCode”:0000C0A801020528

    cJSON_AddStringToObject(cjs_head, "cmd", "setWhiteList");
  //  cJSON_AddNumberToObject(cjs_head, "passCode", gui_js_api_msg_id++);



	cJSON *cjs_attrLst  = cJSON_CreateArray();				//创建一个数组  cjs_attrLst

    if (cjs_attrLst == NULL)
    {
        goto lab_exit;
    }



    for(cnt=0;cnt< num;cnt++)   //cjs_data[cnt]
    {   

        cjs_data[cnt] = cJSON_CreateObject();   //创建一个对象data
        if (cjs_data[cnt] == NULL)
        {
            goto lab_exit;
        }
        

        memset(dev_name_str,0,sizeof(dev_name_str) );
        //snprintf(dev_name_str,sizeof(dev_name_str),"sensor_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);

          switch( iot_type[cnt] )
          {
            case IOT_SENSOR_temper_humidity:  //temperature and humidity:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"temper_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;

            case IOT_SENSOR_smoke:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"smoke_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_water:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"water_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_battery:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"battery_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_dido: 
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dido_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_air_cond:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"air_cond_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_liquid:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"liquid_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_generator:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"gener_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_ac_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"ac_meter_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_dc_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dc_meter_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;

            default :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"sensor_%x_ch%d_%d",iot_type[cnt],info[cnt].channel,info[cnt].chan_addr);//unkown
            }break;

          }



        cJSON_AddStringToObject(cjs_data[cnt],	"name",	dev_name_str );
        

        cJSON_AddStringToObject(cjs_data[cnt],	"mac",	"FFFFFFFFFFFF" );

        memset(iot_type_str,0,sizeof(iot_type_str) );
        snprintf(iot_type_str,sizeof(iot_type_str),"%x",iot_type[cnt]);
        cJSON_AddStringToObject(cjs_data[cnt],	"pid",	iot_type_str );       

        cJSON_AddNumberToObject(cjs_data[cnt],	"nodeType",CJSON_NODE_TYPE_RS485);    //	info[cnt].node_type );
        cJSON_AddNumberToObject(cjs_data[cnt],	"channel",	info[cnt].channel );        
        cJSON_AddNumberToObject(cjs_data[cnt],	"privAddr",	info[cnt].chan_addr );    


        cJSON_AddItemToArray(cjs_attrLst,	cjs_data[cnt] );	//添加对象到数组中

    }

	cJSON_AddItemToObject(cjs_root,	"body",	cjs_attrLst );	//添加数组对象到跟对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif


    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



void json_write_cmd_set_white_list(dev_mod_info_t* info,iot_node_dev_type_e iot_type)
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
  //  cJSON* cjs_body = NULL;
    cJSON* cjs_data = NULL;
    char*  cjs_str  = NULL;

   char iot_type_str[16]="";
   char dev_name_str[64]="";	

   if(NULL ==info)
   {
     return;
   }


	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_head = cJSON_CreateObject();   //创建一个对象data
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cJSON_AddItemToObject(cjs_root, "head", cjs_head);

	cJSON_AddStringToObject(cjs_head, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(cjs_head, "msgId", gui_js_api_msg_id++);

#if CJSON_TIME_STAMP_ENABLE

//	cJSON_AddNumberToObject(cjs_head, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(cjs_head, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............
	cJSON_AddNumberToObject(cjs_head, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


    // “cmd”:”delWhiteList”,
    // “passCode”:0000C0A801020528

    cJSON_AddStringToObject(cjs_head, "cmd", "setWhiteList");
  //  cJSON_AddNumberToObject(cjs_head, "passCode", gui_js_api_msg_id++);



	cJSON *cjs_attrLst  = cJSON_CreateArray();				//创建一个数组  cjs_attrLst

    if (cjs_attrLst == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象data
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


    
    memset(dev_name_str,0,sizeof(dev_name_str) );
   // snprintf(dev_name_str,sizeof(dev_name_str),"sensor_ch%d_%d",info->channel,info->chan_addr);


          switch( iot_type )
          {
            case IOT_SENSOR_temper_humidity:  //temperature and humidity:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"temper_ch%d_%d",info->channel,info->chan_addr);
            }break;

            case IOT_SENSOR_smoke:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"smoke_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_water:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"water_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_battery:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"battery_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_dido: 
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dido_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_air_cond:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"air_cond_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_liquid:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"liquid_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_generator:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"gener_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_ac_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"ac_meter_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_dc_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dc_meter_ch%d_%d",info->channel,info->chan_addr);
            }break;

            default :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"sensor_%x_ch%d_%d",iot_type,info->channel,info->chan_addr);//unkown
            }break;

          }






    cJSON_AddStringToObject(cjs_data,	"name",	dev_name_str );
    

    cJSON_AddStringToObject(cjs_data,	"mac",	"FFFFFFFFFFFF" );

    memset(iot_type_str,0,sizeof(iot_type_str) );
    snprintf(iot_type_str,sizeof(iot_type_str),"%x",iot_type);
    cJSON_AddStringToObject(cjs_data,	"pid",	iot_type_str );
    
                             //表示485节点， 为0plc节点
    cJSON_AddNumberToObject(cjs_data,	"nodeType",	 CJSON_NODE_TYPE_RS485);   //info->node_type
    cJSON_AddNumberToObject(cjs_data,	"channel",	info->channel );        
    cJSON_AddNumberToObject(cjs_data,	"privAddr",	info->chan_addr );    


     cJSON_AddItemToArray(cjs_attrLst,	cjs_data );	//添加对象到数组中

	cJSON_AddItemToObject(cjs_root,	"body",	cjs_attrLst );	//添加数组对象到跟对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif





    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }



#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}










/*------------------------------------------------------------------ 
3.-21  删除白名单  delWhiteList
{
    “head”:{
             “cmd”:”delWhiteList”,
 },
“body”:[    // 删除指定设备
  {“mac”:”112233445567”, “nodeType”:1, “channel”:1, “privAddr”:3},  
{“mac”:”112233445566”, “nodeType”:1, “channel”:1, “privAddr”:4}

],
}

上行
{
“head”:{
       ..........
       “response”:”delWhiteList”
},
    “errCode”:0
}


----------------------------------------------------------------- */
/////num 不能超过16个
void json_write_cmd_del_white_list_more(dev_mod_info_t* info,iot_node_dev_type_e* iot_type,uint8_t num)
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
  //  cJSON* cjs_body = NULL;

    char*  cjs_str  = NULL;

   char iot_type_str[16]="";
   char dev_name_str[64]="";
   
   
 #define  MAX_CJS_DATA_LENGTH (16U)  
cJSON* cjs_data[MAX_CJS_DATA_LENGTH];


uint8_t  cnt; //cjs_cnt

   if(NULL ==info)
   {
     return;
   }


   if(num>=MAX_CJS_DATA_LENGTH)
   {
     return;
   }



	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_head = cJSON_CreateObject();   //创建一个对象data
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cJSON_AddItemToObject(cjs_root, "head", cjs_head);

	cJSON_AddStringToObject(cjs_head, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(cjs_head, "msgId", gui_js_api_msg_id++);

#if CJSON_TIME_STAMP_ENABLE

//	cJSON_AddNumberToObject(cjs_head, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(cjs_head, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............
	cJSON_AddNumberToObject(cjs_head, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


    // “cmd”:”delWhiteList”,
    // “passCode”:0000C0A801020528

    cJSON_AddStringToObject(cjs_head, "cmd", "delWhiteList");
  //  cJSON_AddNumberToObject(cjs_head, "passCode", gui_js_api_msg_id++);



	cJSON *cjs_attrLst  = cJSON_CreateArray();				//创建一个数组  cjs_attrLst

    if (cjs_attrLst == NULL)
    {
        goto lab_exit;
    }



    for(cnt=0;cnt< num;cnt++)   //cjs_data[cnt]
    {   

        cjs_data[cnt] = cJSON_CreateObject();   //创建一个对象data
        if (cjs_data[cnt] == NULL)
        {
            goto lab_exit;
        }
        

        memset(dev_name_str,0,sizeof(dev_name_str) );
 //       snprintf(dev_name_str,sizeof(dev_name_str),"sensor_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);

          switch( iot_type[cnt] )
          {
            case IOT_SENSOR_temper_humidity:  //temperature and humidity:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"temper_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;

            case IOT_SENSOR_smoke:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"smoke_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_water:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"water_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_battery:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"battery_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_dido: 
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dido_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_air_cond:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"air_cond_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_liquid:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"liquid_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_generator:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"gener_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_ac_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"ac_meter_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;
            case IOT_SENSOR_dc_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dc_meter_ch%d_%d",info[cnt].channel,info[cnt].chan_addr);
            }break;

            default :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"sensor_%x_ch%d_%d",iot_type[cnt],info[cnt].channel,info[cnt].chan_addr);//unkown
            }break;

          }

        cJSON_AddStringToObject(cjs_data[cnt],	"name",	dev_name_str );
        
        cJSON_AddStringToObject(cjs_data[cnt],	"mac",	"FFFFFFFFFFFF" );

        memset(iot_type_str,0,sizeof(iot_type_str) );
        snprintf(iot_type_str,sizeof(iot_type_str),"%x",iot_type[cnt]);
        cJSON_AddStringToObject(cjs_data[cnt],	"pid",	iot_type_str );       

        cJSON_AddNumberToObject(cjs_data[cnt],	"nodeType",	CJSON_NODE_TYPE_RS485);   //info[cnt].node_type );
        cJSON_AddNumberToObject(cjs_data[cnt],	"channel",	info[cnt].channel );        
        cJSON_AddNumberToObject(cjs_data[cnt],	"privAddr",	info[cnt].chan_addr );    

        cJSON_AddItemToArray(cjs_attrLst,	cjs_data[cnt] );	//添加对象到数组中

    }

	cJSON_AddItemToObject(cjs_root,	"body",	cjs_attrLst );	//添加数组对象到跟对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif


    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


	printf("%s\n",cjs_str);		////输出字符串-----在socket 发送的时候有printf，这里不重复打印

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}



void json_write_cmd_del_white_list(dev_mod_info_t* info,iot_node_dev_type_e iot_type)
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
  //  cJSON* cjs_body = NULL;
    cJSON* cjs_data = NULL;
    char*  cjs_str  = NULL;

   char iot_type_str[16]="";
   char dev_name_str[64]="";	

   if(NULL ==info)
   {
     return;
   }


	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_head = cJSON_CreateObject();   //创建一个对象data
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cJSON_AddItemToObject(cjs_root, "head", cjs_head);

	cJSON_AddStringToObject(cjs_head, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(cjs_head, "msgId", gui_js_api_msg_id++);

#if CJSON_TIME_STAMP_ENABLE

//	cJSON_AddNumberToObject(cjs_head, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(cjs_head, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............
	cJSON_AddNumberToObject(cjs_head, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


    // “cmd”:”delWhiteList”,
    // “passCode”:0000C0A801020528

    cJSON_AddStringToObject(cjs_head, "cmd", "delWhiteList");
  //  cJSON_AddNumberToObject(cjs_head, "passCode", gui_js_api_msg_id++);



	cJSON *cjs_attrLst  = cJSON_CreateArray();				//创建一个数组  cjs_attrLst

    if (cjs_attrLst == NULL)
    {
        goto lab_exit;
    }

	cjs_data = cJSON_CreateObject();   //创建一个对象data
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }


    
    memset(dev_name_str,0,sizeof(dev_name_str) );
//    snprintf(dev_name_str,sizeof(dev_name_str),"sensor_ch%d_%d",info->channel,info->chan_addr);

          switch( iot_type )
          {
            case IOT_SENSOR_temper_humidity:  //temperature and humidity:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"temper_ch%d_%d",info->channel,info->chan_addr);
            }break;

            case IOT_SENSOR_smoke:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"smoke_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_water:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"water_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_battery:
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"battery_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_dido: 
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dido_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_air_cond:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"air_cond_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_liquid:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"liquid_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_generator:   
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"gener_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_ac_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"ac_meter_ch%d_%d",info->channel,info->chan_addr);
            }break;
            case IOT_SENSOR_dc_meter :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"dc_meter_ch%d_%d",info->channel,info->chan_addr);
            }break;

            default :
            {
              snprintf(dev_name_str,sizeof(dev_name_str),"sensor_%x_ch%d_%d",iot_type,info->channel,info->chan_addr);    //unkown
            }break;

          }

    cJSON_AddStringToObject(cjs_data,	"name",	dev_name_str );
    

    cJSON_AddStringToObject(cjs_data,	"mac",	"FFFFFFFFFFFF" );

    memset(iot_type_str,0,sizeof(iot_type_str) );
    snprintf(iot_type_str,sizeof(iot_type_str),"%x",iot_type);
    cJSON_AddStringToObject(cjs_data,	"pid",	iot_type_str );
    

    cJSON_AddNumberToObject(cjs_data,	"nodeType",	CJSON_NODE_TYPE_RS485); // info->node_type );
    cJSON_AddNumberToObject(cjs_data,	"channel",	info->channel );        
    cJSON_AddNumberToObject(cjs_data,	"privAddr",	info->chan_addr );    


     cJSON_AddItemToArray(cjs_attrLst,	cjs_data );	//添加对象到数组中

	cJSON_AddItemToObject(cjs_root,	"body",	cjs_attrLst );	//添加数组对象到跟对象


    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif


    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}


/*----------------------------------------------------------------- 
{"head":{"gatewayId":"gw_CC0500CFB180","msgId":496,"cmd":"delWhiteList"},"data":{"delAll":1}}
删除全部：{
	"data": {
		"delAll": 1
	},
	"head": {
		"gatewayId": "gw_1C32830600EB",
		"cmd": "delWhiteList"
	}
}

----------------------------------------------------------------- */


void json_write_cmd_clear_white_list(void )
{
    cJSON* cjs_root = NULL;  
    cJSON* cjs_head = NULL;
    cJSON* cjs_data = NULL;

    char*  cjs_str  = NULL;

	cjs_root = cJSON_CreateObject();   //创建一个对象
    if (cjs_root == NULL)
    {
        goto lab_exit;
    }


	cjs_head = cJSON_CreateObject();   //创建一个对象data
    if (cjs_head == NULL)
    {
        goto lab_exit;
    }

	cJSON_AddItemToObject(cjs_root, "head", cjs_head);

	cJSON_AddStringToObject(cjs_head, "gatewayId", get_gateway_id() );
	cJSON_AddNumberToObject(cjs_head, "msgId", gui_js_api_msg_id++);

#if CJSON_TIME_STAMP_ENABLE

//	cJSON_AddNumberToObject(cjs_head, "timeStamp", timeStamp);//-----这个时间戳还有问题
	//cJSON_AddNumberToObject(cjs_head, "timeStamp", 0);/////时间戳暂时取0------------------取0时读数据没有返回，log提示deviceTime=1740815849, cmdTime=12345678, json cmd time stamp old..............
	cJSON_AddNumberToObject(cjs_head, "timeStamp", now_time_stamp );/////时间戳暂--gui_js_api_timeStamp

#endif


    // “cmd”:”delWhiteList”,
    // “passCode”:0000C0A801020528

    cJSON_AddStringToObject(cjs_head, "cmd", "delWhiteList");
  //  cJSON_AddNumberToObject(cjs_head, "passCode", gui_js_api_msg_id++);


	cjs_data = cJSON_CreateObject();   //创建一个对象data
    if (cjs_data == NULL)
    {
        goto lab_exit;
    }

	// "data": {
	// 	"delAll": 1
	// },

     cJSON_AddNumberToObject(cjs_data,	"delAll",	1 );
    
	cJSON_AddItemToObject(cjs_root,	"data",	cjs_data );	//添加数组对象到跟对象



    //JSON数据结构转换为JSON字符串
#if CJSON_PRINT_UNFORM_ENABLE
	cjs_str = cJSON_PrintUnformatted(cjs_root);    //没有空格符的格式=====提高通信效率------
#else
	cjs_str = cJSON_Print(cjs_root);		         // 有空格符的格式------便于人工阅读识别-------------
#endif




    if (cjs_str == NULL)
    {
    	printf("cJSON_Print error!\n");	         
        goto lab_exit;
    }


#if GUI_CJSON_PRINT_ENABLE
	printf("%s\n",cjs_str);		//输出字符串---这部分与socket 发送打印重复
#endif

	//send(cjs_str);      //发送数据

    //返回值 0---发送失败，1---发送成功
    gw_ktj_TCP_ClientSend( (uint8_t*)cjs_str, strlen(cjs_str) );
    
  //  free(cjs_str );   //释放内存空间---尚未确定是否需要这步---????--
    cJSON_free(cjs_str ); 

lab_exit:

    if ( cjs_root != NULL)
    {
	    cJSON_Delete(cjs_root);		//清除结构体
    }

    cjs_root = NULL;  
    cjs_str = NULL;


}













// invalid storage class for function 'search_cmd_all_match_adv'

//static  read_back_st *search_cmd_all_match_adv(const char* pstr, read_back_st * pcmd_tab)   //不能用static
const read_back_st *search_cmd_all_match_adv(const char* pstr, const read_back_st * pcmd_tab)
{
    //while( pcmd_tab->cmd !=0 ) { // bug code 

    for(uint8_t i=0; i<READ_BACK_TAB_MAX;i++) 
    {
        if ( strcmp(pcmd_tab->cmd, pstr)==0 ) {
            return pcmd_tab;//相等
        } else { //不等
            pcmd_tab++;
        }
    }

    return  NULL;
}



//返回0标查找成功，返回<0 查找失败
int json_cmd_adv_process(const char *pcmd, const read_back_st *pcmd_tab, const char *pjson_str, const void *param)
{
	const read_back_st *cmd_ptr;

    cmd_ptr = search_cmd_all_match_adv(pcmd, pcmd_tab);
    
    if ( NULL ==cmd_ptr) {
        log_debug("no cmd fit\n");       
        return -1;
    }


    if ( NULL ==cmd_ptr->func ) 
    {
        log_debug("no cmd fit\n");       
        return -1;        
    }else {
        log_debug("cmd fit\n");
        cmd_ptr->func(pjson_str, param);
		return 0;
    }
    
}




void json_cmd_decode(const char *pcString)
{
	cJSON *json      = NULL;
	cJSON *json_head = NULL;
	cJSON *json_item = NULL;
	cJSON *json_cmd  = NULL;

    printf("%s()\n",__FUNCTION__);

	json = cJSON_Parse(pcString);
	if ( NULL== json ) { 	// not json string
		log_debug("no json\n");
        goto label_end;
	}

    
	json_head = cJSON_GetObjectItem(json, "head");

    if( NULL== json_head) {
        goto label_end;
    }

		json_item = cJSON_GetObjectItem(json_head, "gatewayId");
		if( NULL== json_item) {
            goto label_end;
        }

        if(strcmp(json_item->valuestring, get_gateway_id() )==0) {

            log_debug("geteway_id ok =%s\n",json_item->valuestring);
        }else{
            log_debug("geteway_id not match =%s\n",json_item->valuestring);
            goto label_end; 
        }
    

        json_cmd = cJSON_GetObjectItem(json_head, "response");
        if(NULL== json_cmd) {
            goto label_end;
        }
        
        //返回0标查找成功，返回<0 查找失败
		if( 0==json_cmd_adv_process(cJSON_GetStringValue(json_cmd), read_back_tab, pcString, NULL) ) 
        {
	        log_debug("rx cmd:");            
		    log_debug("%s\n", cJSON_GetStringValue(json_cmd) );			
		}else{
            log_debug("rx server cmd error!\n");
        }


label_end:

	if (json) {
		cJSON_Delete(json);
	}

return  ; 	  

} 












